zoukankan      html  css  js  c++  java
  • SpringBoot重点详解--使用Junit进行单元测试

    目录

    添加依赖与配置

    ApplicationContext测试

    Environment测试

    MockBean测试

    Controller测试

    情况一

    情况二

    方法一

    方法二


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

    添加依赖与配置

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

    1. <parent>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-parent</artifactId>
    4. <version>1.5.6.RELEASE</version>
    5. </parent>
    6. <dependencies>
    7. <!-- 添加MySQL依赖 -->
    8. <dependency>
    9. <groupId>mysql</groupId>
    10. <artifactId>mysql-connector-java</artifactId>
    11. </dependency>
    12. <!-- 添加JDBC依赖 -->
    13. <dependency>
    14. <groupId>org.springframework.boot</groupId>
    15. <artifactId>spring-boot-starter-data-jpa</artifactId>
    16. </dependency>
    17. <dependency>
    18. <groupId>org.springframework.boot</groupId>
    19. <artifactId>spring-boot-starter-web</artifactId>
    20. </dependency>
    21. <!-- 引入单元测试依赖 -->
    22. <dependency>
    23. <groupId>org.springframework.boot</groupId>
    24. <artifactId>spring-boot-starter-test</artifactId>
    25. <scope>test</scope>
    26. </dependency>
    27. </dependencies>

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

    1. #########################################################
    2. ### Spring DataSource -- DataSource configuration ###
    3. #########################################################
    4. spring.datasource.url=jdbc:mysql://localhost:3306/dev1?useUnicode=true&characterEncoding=utf8
    5. spring.datasource.driverClassName=com.mysql.jdbc.Driver
    6. spring.datasource.username=root
    7. spring.datasource.password=123456
    8. #########################################################
    9. ### Java Persistence Api -- Spring jpa configuration ###
    10. #########################################################
    11. # Specify the DBMS
    12. spring.jpa.database = MYSQL
    13. # Show or not log for each sql query
    14. spring.jpa.show-sql = true
    15. # Hibernate ddl auto (create, create-drop, update)
    16. spring.jpa.hibernate.ddl-auto = update
    17. # Naming strategy
    18. #[org.hibernate.cfg.ImprovedNamingStrategy #org.hibernate.cfg.DefaultNamingStrategy]
    19. spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
    20. # stripped before adding them to the entity manager)
    21. spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

    ApplicationContext测试

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

    1. @RunWith(SpringRunner.class) // 等价于使用 @RunWith(SpringJUnit4ClassRunner.class)
    2. @SpringBootTest(classes = { MyApplication.class, TestConfig.class })
    3. public class ApplicationContextTest {
    4. @Autowired
    5. private ApplicationContext context;
    6. @Autowired
    7. private UserDao userDao;
    8. @Test
    9. public void testUserDao() {
    10. userDao.addUser(18, "pengjunlee");
    11. }
    12. @Test
    13. public void testConfiguration() {
    14. Runnable bean = context.getBean(Runnable.class);
    15. Assert.assertNotNull(bean);
    16. bean.run();
    17. }
    18. }

    UserDao定义如下。  

    1. @Repository
    2. public class UserDao {
    3. @Autowired
    4. private JdbcTemplate jdbcTemplate;
    5. @Transactional
    6. public void addUser(Integer userAge, String userName) {
    7. String sql = "insert into tbl_user (age,name) values ('" + userAge + "','" + userName + "');";
    8. jdbcTemplate.execute(sql);
    9. }
    10. }

    TestConfig定义如下。 

    1. /**
    2. * @TestConfiguration注解的配置内的Bean仅在测试时装配
    3. */
    4. @TestConfiguration
    5. public class TestConfig {
    6. @Bean
    7. public Runnable createRunnable(){
    8. return ()->{
    9. System.out.println("This is a test Runnable bean...");
    10. };
    11. }
    12. }

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

    Environment测试

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

    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest(properties = { "app.token=pengjunlee" })
    3. public class EnvironmentTest {
    4. @Autowired
    5. private Environment env;
    6. @Autowired
    7. private ConfigurableEnvironment cenv;
    8. @Before
    9. public void init() {
    10. EnvironmentTestUtils.addEnvironment(cenv, "app.secret=55a4b77eda");
    11. }
    12. @Test
    13. public void testEnvironment() {
    14. System.out.println(env.getProperty("spring.datasource.url"));
    15. Assert.assertEquals("pengjunlee", env.getProperty("app.token"));
    16. Assert.assertEquals("55a4b77eda", cenv.getProperty("app.secret"));
    17. }
    18. @Test
    19. @Ignore // 忽略测试方法
    20. public void testIgnore() {
    21. System.out.println("你看不见我...");
    22. }
    23. }

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

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

    MockBean测试

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

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

    1. public interface IUserService {
    2. Integer getUserAge(Long userId);
    3. }

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

    1. @RunWith(SpringRunner.class)
    2. public class MockBeanTest {
    3. @MockBean
    4. private IUserService userService;
    5. @SuppressWarnings("unchecked")
    6. @Test(expected = NullPointerException.class)
    7. public void testMockBean() {
    8. BDDMockito.given(userService.getUserAge(2L)).willReturn(Integer.valueOf(18));
    9. BDDMockito.given(userService.getUserAge(0L)).willReturn(Integer.valueOf(0));
    10. BDDMockito.given(userService.getUserAge(null)).willThrow(NullPointerException.class);
    11. Assert.assertEquals(Integer.valueOf(18), userService.getUserAge(2L));
    12. Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(0L));
    13. Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(null));
    14. }
    15. }

    Controller测试

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

    情况一

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

    1. @RestController
    2. @RequestMapping("/user")
    3. public class UserController01 {
    4. @GetMapping("/home")
    5. public String homeUser(@RequestParam(name = "name", required = true) String userName) {
    6. if (null == userName || userName.trim() == "") {
    7. return "you are nobody...";
    8. }
    9. return "This is " + userName + "'s home...";
    10. }
    11. }

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

    1. @RunWith(SpringRunner.class)
    2. @WebMvcTest(controllers = { UserController01.class })
    3. public class ControllerTest01 {
    4. @Autowired
    5. private MockMvc mvc;
    6. @Test
    7. public void testAddUser() throws Exception {
    8. mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", ""))
    9. .andExpect(MockMvcResultMatchers.status().isOk())
    10. .andExpect(MockMvcResultMatchers.content().string("you are nobody..."));
    11. mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", "pengjunlee"))
    12. .andExpect(MockMvcResultMatchers.status().isOk())
    13. .andExpect(MockMvcResultMatchers.content().string("This is pengjunlee's home..."));
    14. }
    15. }

    情况二

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

    1. @RestController
    2. @RequestMapping("/user")
    3. public class UserController02 {
    4. @Autowired
    5. private UserDao userDao;
    6. @GetMapping("/add")
    7. public String addUser(@RequestParam(name = "age", required = false, defaultValue = "0") Integer userAge,
    8. @RequestParam(name = "name", required = true) String userName) {
    9. if (userAge <= 0 || null == userName || userName.trim() == "") {
    10. return "0";
    11. }
    12. userDao.addUser(userAge, userName);
    13. return "1";
    14. }
    15. }

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

    方法一

    利用TestRestTemplate进行测试。 

    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    3. public class ControllerTest02 {
    4. @Autowired
    5. private TestRestTemplate template;
    6. @Test
    7. public void testAddUser() {
    8. String result1 = template.getForObject("/user/add?name=pengjunlee", String.class);
    9. Assert.assertEquals("0", result1);
    10. String result2 = template.getForObject("/user/add?age=20&name=Tracy", String.class);
    11. Assert.assertEquals("1", result2);
    12. }
    13. }

    方法二

    利用MockMvc进行测试。 

    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    3. @AutoConfigureMockMvc
    4. public class ControllerTest03 {
    5. @Autowired
    6. private MockMvc mvc;
    7. @Test
    8. public void testAddUser() throws Exception {
    9. mvc.perform(MockMvcRequestBuilders.get("/user/add").param("name", ""))
    10. .andExpect(MockMvcResultMatchers.status().isOk())
    11. .andExpect(MockMvcResultMatchers.content().string("0"));
    12. mvc.perform(MockMvcRequestBuilders.get("/user/add").param("age", "22").param("name", "pengjunlee"))
    13. .andExpect(MockMvcResultMatchers.status().isOk())
    14. .andExpect(MockMvcResultMatchers.content().string("1"));
    15. }
    16. }

    本文项目源码已上传至CSDN,资源地址:https://download.csdn.net/download/pengjunlee/10394302  

    原文地址:https://blog.csdn.net/pengjunlee/article/details/80206615
  • 相关阅读:
    jenkins 分布式部署
    Jenkins2.138配置slave节点时,启动方法只有两个选项
    SIFT特征详解
    OpenCV,计算两幅图像的单应矩阵
    OpenGL新手框架
    OpenGL超级宝典visual studio 2013开发环境配置,GLTools
    归一化变换 Normalizing transformations
    OpenCV2:特征匹配及其优化
    OpenCV2简单的特征匹配
    Qt自适应大小显示图片,添加菜单
  • 原文地址:https://www.cnblogs.com/jpfss/p/10950500.html
Copyright © 2011-2022 走看看