当前位置:   article > 正文

SpringBoot单元测试_import org.springframework.boot.test.context.sprin

import org.springframework.boot.test.context.springboottest;

1、SpringBoot单元测试

单元测试(Unit Test)是为了检验程序的正确性。一个单元可能是单个程序、类、对象、方法等,它是应用程序的最小可测试部件。SpringBoot提供了 spring-boot-starter-test 启动器。通过它,能引入一些有用的测试库。

1.1 快速创建单元测试

(1)在SpringBoot中进行单元测试很简单,它已经自动添加好了Test的Starter依赖,如下:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-test</artifactId>
  4. <scope>test</scope>
  5. </dependency>

(2)只要在“src/test/java”目录下新建一个测试类即可,代码如下:

  1. import com.pjb.entity.UserInfo;
  2. import org.junit.After;
  3. import org.junit.Before;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. /**
  10. * 用户业务逻辑测试类(JUnit4)
  11. * @author pan_junbiao
  12. **/
  13. @SpringBootTest
  14. @RunWith(SpringRunner.class)
  15. public class UserServiceTest
  16. {
  17. @Autowired
  18. private UserService userService;
  19. @Before
  20. public void setUp()
  21. {
  22. }
  23. @After
  24. public void tearDown()
  25. {
  26. }
  27. @Test
  28. public void getUserInfoById()
  29. {
  30. //测试代码
  31. UserInfo userInfo = userService.getUserInfoById(1);
  32. }
  33. }

代码说明:

@SpringBootTest:是SpringBoot用于测试的注解,可指定入口类或测试环境等。

@RunWith(SpringRunner.class):让测试运行与Spring的测试环境。

@Test:表示为一个测试单元。

1.2 测试的回滚

在单元测试中可能会产生垃圾数据,可以开启事务功能进行回滚——在方法或者类头部添加@Transactional注解即可,代码如下:

  1. /**
  2. * 新增员工
  3. * 加上@Transactional注解,开启事务
  4. * 这样测试执行完后就会进行回滚操作
  5. * @author pan_junbiao
  6. */
  7. @Test
  8. @Transactional
  9. public void addStaff()
  10. {
  11. //创建新用户信息
  12. UserInfo userInfo = new UserInfo();
  13. userInfo.setUserName("pan_junbiao的博客");
  14. userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
  15. userInfo.setBlogRemark("您好,欢迎访问 pan_junbiao的博客");
  16. //执行新增操作
  17. userDao.save(userInfo);
  18. }

 

2、JUnit5测试框架

JUnit5是对程序代码进行单元测试的Java框架。它用来编写自动化测试工具,降低测试的难度、减少烦琐性、并有效避免出现程序错误。

2.1 JUnit5注解

所有支持的注解都在包 org.junit.jupiter.api 下;

使用@Test、@TestTemplate、@RepeatedTest、@BeforeAll、@AfterAll、@BeforeEach或@AfterEach注释的方法不能返回值。

注解说明
@Test表示方法是测试方法。与JUnit 4的@Test注释不同,这个注释不声明任何属性,因为JUnit Jupiter中的测试扩展基于它们自己的专用注释进行操作。 
@ParameterizedTest表示方法是参数化测试。
@RepeatedTest表示方法是重复测试的测试模板。
@TestFactory表示方法是动态测试的测试工厂。
@TestInstance用于为带注释的测试类配置测试实例生命周期。
@TestTemplate表示方法是为测试用例设计的模板,根据注册提供程序返回的调用上下文的数量进行多次调用。
@DisplayName声明测试类或测试方法的自定义显示名称。
@BeforeEach表示在当前类中每个@Test、@RepeatedTest、@ParameterizedTest或@TestFactory方法之前执行注释的方法;类似于JUnit 4的@Before。
@AfterEach表示在当前类中的每个@Test、@RepeatedTest、@ParameterizedTest或@TestFactory方法之后,都应该执行带注释的方法;类似于JUnit 4的@After。
@BeforeAll表示应在当前类中的所有@Test、@RepeatedTest、@ParameterizedTest和@TestFactory方法之前执行带注释的方法;类似于JUnit 4的@BeforeClass。
@AfterAll表示在当前类中,所有@Test、@RepeatedTest、@ParameterizedTest和@TestFactory方法都应该执行注释的方法;类似于JUnit 4的@AfterClass。
@Nested表示带注释的类是一个嵌套的、非静态的测试类。@BeforeAll和@AfterAll方法不能直接在 @Nested 测试类中使用,除非使用“每个类”测试实例生命周期。
@Tag用于在类或方法级别声明过滤测试的标记;类似于TestNG中的测试组或JUnit 4中的类别。
@Disabled用于禁用测试类或测试方法;类似于JUnit 4的@Ignore。
@ExtendWith用于注册自定义扩展。

2.2 JUnit5断言(Assertions类)

 JUnit5断言都是 org.junit.jupiter.api.Assertions 中的静态方法断言类。

Asser类中主要方法如下:

方法名称方法描述
assertEquals断言传入的预期值与实际值是相等的。
assertNotEquals断言传入的预期值与实际值是不相等的。
assertArayEquals断言传入的预期数组与实际数组是相等的。
assertNull断言传入的对象是为空。
assertNotNull断言传入的对象是不为空。
assertTrue断言条件为真。
assertFalse断言条件为假。
assertSame断言两个对象引用同一个对象,相当于"==”。
assertNotSame断言两个对象引用不同的对象,相当于"!=”。
assertThat断言实际值是否满足指定的条件。

【示例】SpringBoot 基于 JUnit5 的测试类。

  1. package com.pjb;
  2. import org.junit.jupiter.api.AfterEach;
  3. import org.junit.jupiter.api.BeforeEach;
  4. import org.junit.jupiter.api.Test;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.boot.test.context.SpringBootTest;
  7. /**
  8. * 用户业务逻辑测试类(JUnit5)
  9. * @author pan_junbiao
  10. **/
  11. @SpringBootTest
  12. public class UserServiceTest
  13. {
  14. @BeforeEach
  15. void setUp()
  16. {
  17. }
  18. @AfterEach
  19. void tearDown()
  20. {
  21. }
  22. @Autowired
  23. private UserService userService;
  24. @Test
  25. public void getUserInfoById()
  26. {
  27. //测试代码
  28. UserInfo userInfo = userService.getUserInfoById(1);
  29. }
  30. }

 

3、项目的单元测试

创建SpringBoot项目,实现Controller层、Service层、Dao层的单元测试。

3.1 Controller层的单元测试

Mockito是GitHub上使用最广泛的Mocking框架。它提供简洁的API来测试。Mockito简单易学、可读性强、验证语法简洁。

【示例】使用Mockito框架,对Controller层进行单元测试。

(1)创建UserController(用户信息控制器)。

  1. package com.pjb.controller;
  2. import com.pjb.entity.UserInfo;
  3. import com.pjb.service.UserService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.*;
  6. /**
  7. * 用户信息控制器
  8. * @author pan_junbiao
  9. **/
  10. @RestController
  11. @RequestMapping("user")
  12. public class UserController
  13. {
  14. @Autowired
  15. private UserService userService;
  16. /**
  17. * 获取用户信息
  18. * RESTful接口
  19. */
  20. @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  21. public UserInfo getUserInfo(@PathVariable("id")int userId)
  22. {
  23. UserInfo userInfo = userService.getUserInfoById(userId);
  24. return userInfo;
  25. }
  26. /**
  27. * 根据用户ID,获取用户信息
  28. */
  29. @RequestMapping("/getUserInfoById")
  30. public UserInfo getUserInfoById(@RequestParam(value = "user_id", defaultValue = "0") int userId)
  31. {
  32. UserInfo userInfo = userService.getUserInfoById(userId);
  33. return userInfo;
  34. }
  35. /**
  36. * 新增用户信息
  37. * 参数:接收对象型参数
  38. */
  39. @RequestMapping(value = "/addUserByEntity", method = RequestMethod.POST)
  40. public boolean addUserByEntity(@RequestBody UserInfo userInfo)
  41. {
  42. boolean result = userService.addUser(userInfo);
  43. return result;
  44. }
  45. /**
  46. * 新增用户信息
  47. * 参数:接收多个参数
  48. */
  49. @RequestMapping(value = "/addUserByParam", method = RequestMethod.POST)
  50. public boolean addUserByParam(String userName,String blogUrl,String blogRemark)
  51. {
  52. UserInfo userInfo = new UserInfo();
  53. userInfo.setUserName(userName);
  54. userInfo.setBlogUrl(blogUrl);
  55. userInfo.setBlogRemark(blogRemark);
  56. boolean result = userService.addUser(userInfo);
  57. return result;
  58. }
  59. }

(2)实现Controller层的单元测试。

  1. package com.pjb.controller;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import com.pjb.entity.UserInfo;
  4. import org.junit.Assert;
  5. import org.junit.jupiter.api.AfterEach;
  6. import org.junit.jupiter.api.BeforeEach;
  7. import org.junit.jupiter.api.Test;
  8. import org.junit.runner.RunWith;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.boot.test.context.SpringBootTest;
  11. import org.springframework.http.MediaType;
  12. import org.springframework.test.context.junit4.SpringRunner;
  13. import org.springframework.test.web.servlet.MockMvc;
  14. import org.springframework.test.web.servlet.MvcResult;
  15. import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
  16. import org.springframework.test.web.servlet.setup.MockMvcBuilders;
  17. import org.springframework.util.LinkedMultiValueMap;
  18. import org.springframework.util.MultiValueMap;
  19. import org.springframework.web.context.WebApplicationContext;
  20. /**
  21. * 用户信息控制器测试类
  22. * @author pan_junbiao
  23. **/
  24. @SpringBootTest
  25. @RunWith(SpringRunner.class)
  26. class UserControllerTest
  27. {
  28. //启用Web上下文
  29. @Autowired
  30. private WebApplicationContext webApplicationContext;
  31. private MockMvc mockMvc;
  32. @BeforeEach
  33. private void setUp()
  34. {
  35. //使用上下文构建MockMvc
  36. mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
  37. }
  38. @AfterEach
  39. private void tearDown()
  40. {
  41. }
  42. /**
  43. * 根据用户ID,获取用户信息
  44. * RESTful接口
  45. */
  46. @Test
  47. public void getUserInfo() throws Exception
  48. {
  49. //执行请求(使用GET请求,RESTful接口)
  50. MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/user/{id}",1).accept(MediaType.APPLICATION_JSON_UTF8)).andReturn();
  51. //获取返回编码
  52. int status = mvcResult.getResponse().getStatus();
  53. //获取返回结果
  54. String content = mvcResult.getResponse().getContentAsString();
  55. //断言,判断返回编码是否正确
  56. Assert.assertEquals(200,status);
  57. //将JSON转换为对象
  58. ObjectMapper mapper = new ObjectMapper();
  59. UserInfo userInfo = mapper.readValue(content, UserInfo.class);
  60. //打印结果
  61. System.out.println("用户ID:" + userInfo.getUserId());
  62. System.out.println("用户姓名:" + userInfo.getUserName());
  63. System.out.println("博客地址:" + userInfo.getBlogUrl());
  64. System.out.println("博客信息:" + userInfo.getBlogRemark());
  65. }
  66. /**
  67. * 根据用户ID,获取用户信息
  68. * 使用GET请求
  69. */
  70. @Test
  71. public void getUserInfoById() throws Exception
  72. {
  73. //执行请求(使用GET请求)
  74. MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/user/getUserInfoById").param("user_id","1").accept(MediaType.APPLICATION_JSON_UTF8)).andReturn();
  75. //获取返回编码
  76. int status = mvcResult.getResponse().getStatus();
  77. //获取返回结果
  78. String content = mvcResult.getResponse().getContentAsString();
  79. //断言,判断返回编码是否正确
  80. Assert.assertEquals(200,status);
  81. //将JSON转换为对象
  82. ObjectMapper mapper = new ObjectMapper();
  83. UserInfo userInfo = mapper.readValue(content, UserInfo.class);
  84. //打印结果
  85. System.out.println("用户ID:" + userInfo.getUserId());
  86. System.out.println("用户姓名:" + userInfo.getUserName());
  87. System.out.println("博客地址:" + userInfo.getBlogUrl());
  88. System.out.println("博客信息:" + userInfo.getBlogRemark());
  89. }
  90. /**
  91. * 新增用户信息
  92. * 使用POST请求,传递对象型参数
  93. */
  94. @Test
  95. public void addUserByEntity() throws Exception
  96. {
  97. //创建新用户
  98. UserInfo userParam = new UserInfo();
  99. userParam.setUserName("pan_junbiao的博客");
  100. userParam.setBlogUrl("https://blog.csdn.net/pan_junbiao");
  101. userParam.setBlogRemark("您好,欢迎访问 pan_junbiao的博客");
  102. //将参数转换成JSON对象
  103. ObjectMapper mapper = new ObjectMapper();
  104. String json = mapper.writeValueAsString(userParam);
  105. //执行请求(使用POST请求,传递对象参数)
  106. MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/user/addUserByEntity").content(json).contentType(MediaType.APPLICATION_JSON)).andReturn();
  107. //获取返回编码
  108. int status = mvcResult.getResponse().getStatus();
  109. //获取返回结果
  110. String content = mvcResult.getResponse().getContentAsString();
  111. //断言,判断返回编码是否正确
  112. Assert.assertEquals(200,status);
  113. //断言,判断返回结果是否正确
  114. Assert.assertEquals("true",content);
  115. }
  116. /**
  117. * 多个参数的传递
  118. * 使用POST请求,传递多个参数
  119. */
  120. @Test
  121. public void addUserByParam() throws Exception
  122. {
  123. //多个参数的传递
  124. MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
  125. params.add("userName","pan_junbiao的博客");
  126. params.add("blogUrl","https://blog.csdn.net/pan_junbiao");
  127. params.add("blogRemark","您好,欢迎访问 pan_junbiao的博客");
  128. //执行请求(使用POST请求,传递多个参数)
  129. MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/user/addUserByParam").params(params)).andReturn();
  130. //获取返回编码
  131. int status = mvcResult.getResponse().getStatus();
  132. //获取返回结果
  133. String content = mvcResult.getResponse().getContentAsString();
  134. //断言,判断返回编码是否正确
  135. Assert.assertEquals(200,status);
  136. //断言,判断返回结果是否正确
  137. Assert.assertEquals("true",content);
  138. }
  139. }

执行结果:

3.2 Service层的单元测试

【示例】Service层进行单元测试,使用Assert方法进行断言结果。

  1. package com.pjb.service;
  2. import com.pjb.entity.UserInfo;
  3. import org.junit.Assert;
  4. import org.junit.Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.test.context.junit4.SpringRunner;
  9. /**
  10. * 用户业务逻辑测试类
  11. * @author pan_junbiao
  12. **/
  13. @SpringBootTest
  14. @RunWith(SpringRunner.class)
  15. public class UserServiceTest
  16. {
  17. @Autowired
  18. private UserService userService;
  19. @Test
  20. public void getUserInfoById()
  21. {
  22. //获取用户信息
  23. UserInfo userInfo = userService.getUserInfoById(1);
  24. //断言
  25. Assert.assertEquals(1,userInfo.getUserId());
  26. Assert.assertEquals("pan_junbiao的博客",userInfo.getUserName());
  27. Assert.assertEquals("https://blog.csdn.net/pan_junbiao",userInfo.getBlogUrl());
  28. Assert.assertEquals("您好,欢迎访问 pan_junbiao的博客",userInfo.getBlogRemark());
  29. }
  30. }

3.3 Dao层的单元测试

【示例】Dao层进行单元测试,以及使用@Transactional注解进行回滚操作。

  1. import com.pjb.entity.UserInfo;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.test.context.junit4.SpringRunner;
  7. import org.springframework.transaction.annotation.Transactional;
  8. /**
  9. * 用户信息数据库访问测试类
  10. * @author pan_junbiao
  11. **/
  12. @SpringBootTest
  13. @RunWith(SpringRunner.class)
  14. public class UserDaoTest
  15. {
  16. @Autowired
  17. private UserDao userDao;
  18. /**
  19. * 新增员工
  20. * 加上@Transactional注解,开启事务
  21. * 这样测试执行完后就会进行回滚操作
  22. * @author pan_junbiao
  23. */
  24. @Test
  25. @Transactional
  26. public void addStaff()
  27. {
  28. //创建新用户信息
  29. UserInfo userInfo = new UserInfo();
  30. userInfo.setUserName("pan_junbiao的博客");
  31. userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
  32. userInfo.setBlogRemark("您好,欢迎访问 pan_junbiao的博客");
  33. //执行新增操作
  34. userDao.save(userInfo);
  35. }
  36. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/366915?site
推荐阅读
相关标签
  

闽ICP备14008679号