Springboot单元测试mysql_SpringBoot重点详解--使用Junit进行单元测试

本文详述了在SpringBoot项目中使用Junit进行单元测试的步骤,包括添加相关依赖、配置数据库连接,以及进行ApplicationContext、Environment、MockBean和Controller测试的实例。演示了如何使用@Test注解、@RunWith(SpringRunner.class)、@SpringBootTest等进行测试,并展示了测试用例的执行顺序。
摘要由CSDN通过智能技术生成

目录

本文将对在Springboot中如何使用Junit进行单元测试进行简单示例和介绍,项目的完整目录层次如下图所示。

b5f8a13fccdd6c1def7882d643fe9d20.png

添加依赖与配置

为了保证测试的完整性,本工程POM文件中除引入Junit单元测试依赖外,还额外引入了用来测试JDBC和Controller的JPA和WEB依赖。

org.springframework.boot

spring-boot-starter-parent

1.5.6.RELEASE

mysql

mysql-connector-java

org.springframework.boot

spring-boot-starter-data-jpa

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

同时,在src/main/resources目录下添加核心配置文件application.properties,内容如下。

#########################################################

### Spring DataSource -- DataSource configuration ###

#########################################################

spring.datasource.url=jdbc:mysql://localhost:3306/dev1?useUnicode=true&characterEncoding=utf8

spring.datasource.driverClassName=com.mysql.jdbc.Driver

spring.datasource.username=root

spring.datasource.password=123456

#########################################################

### Java Persistence Api -- Spring jpa configuration ###

#########################################################

# Specify the DBMS

spring.jpa.database = MYSQL

# Show or not log for each sql query

spring.jpa.show-sql = true

# Hibernate ddl auto (create, create-drop, update)

spring.jpa.hibernate.ddl-auto = update

# Naming strategy

#[org.hibernate.cfg.ImprovedNamingStrategy #org.hibernate.cfg.DefaultNamingStrategy]

spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

# stripped before adding them to the entity manager)

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

ApplicationContext测试

在Springboot中使用Junit进行单元测试的方法很简单,只需要在编写的单元测试类上添加两个注解:@RunWith(SpringRunner.class)和@SpringBootTest。

@RunWith(SpringRunner.class) // 等价于使用 @RunWith(SpringJUnit4ClassRunner.class)

@SpringBootTest(classes = { MyApplication.class, TestConfig.class })

public class ApplicationContextTest{

@Autowired

private ApplicationContext context;

@Autowired

private UserDao userDao;

@Test

public void testUserDao(){

userDao.addUser(18, "pengjunlee");

}

@Test

public void testConfiguration(){

Runnable bean = context.getBean(Runnable.class);

Assert.assertNotNull(bean);

bean.run();

}

}

UserDao定义如下。

@Repository

public class UserDao{

@Autowired

private JdbcTemplate jdbcTemplate;

@Transactional

public void addUser(Integer userAge, String userName){

String sql = "insert into tbl_user (age,name) values ('" + userAge + "','" + userName + "');";

jdbcTemplate.execute(sql);

}

}

TestConfig定义如下。

/**

* @TestConfiguration注解的配置内的Bean仅在测试时装配

*/

@TestConfiguration

public class TestConfig{

@Bean

public Runnable createRunnable(){

return ()->{

System.out.println("This is a test Runnable bean...");

};

}

}

提示:@SpringBootTest注解的classes可以指定用来加载Spring容器所使用的配置类,@TestConfiguration注解修饰的配置类内的Bean仅在测试的时候才会装配。

Environment测试

我们可以通过@SpringBootTest注解的properties属性向Environment中设置新的属性,也可以通过使用EnvironmentTestUtils工具类来向ConfigurableEnvironment中添加新的属性。

@RunWith(SpringRunner.class)

@SpringBootTest(properties = { "app.token=pengjunlee" })

public class EnvironmentTest{

@Autowired

private Environment env;

@Autowired

private ConfigurableEnvironment cenv;

@Before

public void init(){

EnvironmentTestUtils.addEnvironment(cenv, "app.secret=55a4b77eda");

}

@Test

public void testEnvironment(){

System.out.println(env.getProperty("spring.datasource.url"));

Assert.assertEquals("pengjunlee", env.getProperty("app.token"));

Assert.assertEquals("55a4b77eda", cenv.getProperty("app.secret"));

}

@Test

@Ignore // 忽略测试方法

public void testIgnore(){

System.out.println("你看不见我...");

}

}

扩展:Junit测试用例执行顺序:@BeforeClass ==> @Before ==> @Test ==> @After ==> @AfterClass 。

注意:在使用Junit对Spring容器进行单元测试时,若在src/test/resources 目录下存在核心配置文件,Spring容器将会只加载src/test/resources 目录下的核心配置文件,而不再加载src/main/resources 目录下的核心配置文件。

MockBean测试

我们可以通过@MockBean注解来对那些未添加实现的接口进行模拟测试,预先设定好调用方法期待的返回值,然后再进行测试。

例如,有如下的IUserService接口,定义了一个getUserAge()方法用来根据用户的ID来查询用户的年龄。

public interface IUserService{

Integer getUserAge(Long userId);

}

使用@MockBean来对IUserService接口进行模拟测试,测试代码如下。

@RunWith(SpringRunner.class)

public class MockBeanTest{

@MockBean

private IUserService userService;

@SuppressWarnings("unchecked")

@Test(expected = NullPointerException.class)

public void testMockBean(){

BDDMockito.given(userService.getUserAge(2L)).willReturn(Integer.valueOf(18));

BDDMockito.given(userService.getUserAge(0L)).willReturn(Integer.valueOf(0));

BDDMockito.given(userService.getUserAge(null)).willThrow(NullPointerException.class);

Assert.assertEquals(Integer.valueOf(18), userService.getUserAge(2L));

Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(0L));

Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(null));

}

}

Controller测试

在Springboot中可以通过TestRestTemplate和MockMvc来对Controller进行测试,有以下两种情况。

情况一

Controller中未装配任何其他Spring容器中的Bean,例如下面这个控制器。

@RestController

@RequestMapping("/user")

public class UserController01{

@GetMapping("/home")

public String homeUser(@RequestParam(name = "name", required = true) String userName){

if (null == userName || userName.trim() == "") {

return "you are nobody...";

}

return "This is " + userName + "'s home...";

}

}

此时无需启动Spring容器,可直接使用MockMvc来对Controller进行模拟测试,测试代码如下。

@RunWith(SpringRunner.class)

@WebMvcTest(controllers = { UserController01.class })

public class ControllerTest01{

@Autowired

private MockMvc mvc;

@Test

public void testAddUser() throws Exception{

mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", ""))

.andExpect(MockMvcResultMatchers.status().isOk())

.andExpect(MockMvcResultMatchers.content().string("you are nobody..."));

mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", "pengjunlee"))

.andExpect(MockMvcResultMatchers.status().isOk())

.andExpect(MockMvcResultMatchers.content().string("This is pengjunlee's home..."));

}

}

情况二

Controller中需装配其他Spring容器中的Bean,例如下面这个控制器。

@RestController

@RequestMapping("/user")

public class UserController02{

@Autowired

private UserDao userDao;

@GetMapping("/add")

public String addUser(@RequestParam(name = "age", required = false, defaultValue = "0") Integer userAge,

@RequestParam(name = "name", required = true) String userName){

if (userAge <= 0 || null == userName || userName.trim() == "") {

return "0";

}

userDao.addUser(userAge, userName);

return "1";

}

}

此时除了要启动Spring容器,还需要启动内嵌的WEB环境,有以下两种方法。

方法一

利用TestRestTemplate进行测试。

@RunWith(SpringRunner.class)

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

public class ControllerTest02{

@Autowired

private TestRestTemplate template;

@Test

public void testAddUser(){

String result1 = template.getForObject("/user/add?name=pengjunlee", String.class);

Assert.assertEquals("0", result1);

String result2 = template.getForObject("/user/add?age=20&name=Tracy", String.class);

Assert.assertEquals("1", result2);

}

}

方法二

利用MockMvc进行测试。

@RunWith(SpringRunner.class)

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

@AutoConfigureMockMvc

public class ControllerTest03{

@Autowired

private MockMvc mvc;

@Test

public void testAddUser() throws Exception{

mvc.perform(MockMvcRequestBuilders.get("/user/add").param("name", ""))

.andExpect(MockMvcResultMatchers.status().isOk())

.andExpect(MockMvcResultMatchers.content().string("0"));

mvc.perform(MockMvcRequestBuilders.get("/user/add").param("age", "22").param("name", "pengjunlee"))

.andExpect(MockMvcResultMatchers.status().isOk())

.andExpect(MockMvcResultMatchers.content().string("1"));

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值