springboot单元测试
Posted xiha_zhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot单元测试相关的知识,希望对你有一定的参考价值。
当单元测试代码不需要Springboot功能,可以直接编写Junit测试代码
public class JunitTest
@Test
public void test()
System.out.println("Junit Test");
spring框架提供测试模块spring-test,用于应用程序的集成测试,在springboot中,通过spring-boot-starter-test启动器来快速开启和使用。
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringBootTest
@Autowired
private UserMapper userMapper;
@Test
public void test()
System.out.println(userMapper.get(1).getName());
@SpringBootTest注解是普通spring(非springboot)项目中编写测试代码使用的@ContextConfiguration注解的替代品。当运行测试类时,它会从当前测试类所在包一层层向上搜索,直到找到@SpringBootApplication或@SpringBootConfiguration注释类为止,以此来确定如何装载spring应用程序的上下文资源。也可以通过classes属性手工指定装载的主配置文件。
SpringBoot MockMvc测试
@SpringBootTest
@RunWith(SpringRunner.class)
@WebAppConfiguration
public class SpringBootWebTest
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Resource
private SecurityManager securityManager;
private Subject subject;
private MockHttpServletRequest mockHttpServletRequest;
private MockHttpServletResponse mockHttpServletResponse;
@Before
public void setUp()
/**
* MockMvcBuilders提供两方法
* public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context)
* return new DefaultMockMvcBuilder(context);
*
* public static StandaloneMockMvcBuilder standaloneSetup(Object... controllers)
* return new StandaloneMockMvcBuilder(controllers);
*
*
* 通过build()方法构造MockMvc对象
*/
// 独立安装测试
// mockMvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
// 集成web环境测试(这种方式并不会集成真正的web环境,而是通过相应的Mock Api进行模拟测试,
// 无需启动服务器
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
// 模拟登录
mockHttpServletRequest = new MockHttpServletRequest(context.getServletContext());
mockHttpServletResponse = new MockHttpServletResponse();
MockHttpSession mockHttpSession = new MockHttpSession(content.getServletContext());
mockHttpServletRequest.setSession(mockHttpSession);
SecurityUtils.setSecurityManager(securityManager);
// 模拟登录
private void login(String userName, String password)
subject = new WebSubject.Builder(mockHttpServletRequest, mockHttpServletResponse).buildWebSubject();
UsernamePasswordToken token = new UsernamePasswordToken(userName, password, true);
subject.login(token);
ThreadContext.bind(subject);
/**
* mockMvc.perform 执行一个请求
* MockMvcRequestBuilders.get("...") 构造一个请求
* ResultActions.param 添加请求参数
* ResultActions.accept 设置返回类型
* ResultActions.andExpect 添加断言
* ResultActions.andDo 结果处理器,MockMvcResultHandlers.print()输出整个响应结果信息
* ResultActions.andReturn 执行完成后返回相应的结果
*/
@Test
public void testGet()
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/user")
.param("id", "1");
mockMvc.perform(builder)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
@Test
public void testUpd() throws Exception
User user = new User();
user.setId(1);
user.setName("zhu");
user.setCId("002");
ObjectMapper mapper = new ObjectMapper();
mockMvc.perform(MockMvcRequestBuilders.post("/updUser")
.content(mapper.writeValueAsString(user))
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andDo(MockMvcResultHandlers.print());
Mockito测试(不依赖数据库)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
public class UserControllerTest
@InjectMocks
UserController userController;
@Mock
private UserServiceImpl userService;
private MockMvc mvc;
@Before
public void setUp()
MockitoAnnotations.openMocks(this);
mvc = MockMvcBuilders.standaloneSetup(userController).build();
@Test
public void list() throws Exception
mockStatic(AbcUtil.class);
when(AbcUtil.abc(any())).thenReturn("abc");
Assert.assertEquals(AbcUtil.abc("cccc"), "abc");
when(userService.selectUserList(any())).thenReturn(new ArrayList<>());
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/user/list").param("id", "1");
// @RequestBody接收对象
JSONObject obj = new JSONObject();
obj.put("name", "z");
MockHttpServletRequestBuilder requestBuilder1 = MockMvcRequestBuilders.post("/test")
.cookie(new Cookie("cookieName","value"))
.contentType(MediaType.APPLICATION_JSON).content(obj.toJSONString());
// MultipartFile文件上传请求
MockMultipartFile multipartFile = new MockMultipartFile("file", "abc", "txt", "啊".getBytes(StandardCharsets.UTF_8));
MockHttpServletRequestBuilder requestBuilder2 = MockMvcRequestBuilders.multipart("/file/upload").file(multipartFile).param("id", "123");
ResultActions resultActions = mvc.perform(requestBuilder);
resultActions.andReturn().getResponse().setCharacterEncoding("utf-8");
resultActions.andDo(MockMvcResultHandlers.print());
resultActions.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(200));
MvcResult mvcResult = resultActions.andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
// 获取状态码
int status = response.getStatus();//500状态码 302状态码 404状态码 200状态码等
// 获取返回 @ResponseBody json字符串 : 进行反序列化处理即可
String contentAsString = response.getContentAsString();
// 返回ModelAndView 获取里面的页面路径
// 代码: model.setViewName("/index");
ModelAndView mv = mvcResult.getModelAndView();
String url = mv.getViewName(); //得到/index
// 返回ModelAndView 判断里面state参数
// model.addObject("state", 1);
ModelAndView mv1 = mvcResult.getModelAndView();
Map<String, Object> map = mv1.getModel();
Integer state = (Integer) map.get("state");
// 返回ModelAndView 判断里面的集合/map/对象
// PageInfo<User> list=new PageInfo<>();
// model.addObject("AdminList", list);
ModelAndView mv2 = mvcResult.getModelAndView();
Map<String, Object> model = mv2.getModel();
((PageInfo<User>) model.get("AdminList")).getList().size();
java.lang.IllegalArgumentException: At least one base package must be specified
原因:包扫描没有配value值
解决: 启动类@MapperScan("value")
java.lang.ClassNotFoundException: org.springframework.transaction.TransactionException
原因:创建schedule的时候初始化报错,找不到spring事务相关的类
解决:pom配置文件添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class...
原因:在使用Json时,fasterxml.jackson将对象转换为json报错
解决:在实体类上加注解 @JsonIgnoreProperties(value = "hibernateLazyInitializer", "handler" ) 或者, 关联查询fetchType = “lazy" 改为默认eager
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named '...'
原因: Mapper方法参数没加注解@Param("...")
javax.websocket.server.ServerContainer not available
原因SpringBootTest在启动的时候不会启动服务器,所以WebSocket自然会报错,这个时候需要添加选项webEnvironment,以便提供一个测试的web环境
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
以上是关于springboot单元测试的主要内容,如果未能解决你的问题,请参考以下文章