SpringBoot单元测试
// 注解部分
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@MockBean
private AuthInterceptor authInterceptor;
@MockBean
private AuthInitEvent authInitEvent;
@MockBean
private AuthUtil authUtil;
@Before
public void setupMockMvc(){
mvc = MockMvcBuilders.webAppContextSetup(context).build(); //初始化MockMvc对象
}
@Test
@Transactional
public void test() {
String jsonString = JSONObject.toJSONString();
// Mock部分
Mockito.when(authInterceptor.preHandle(Mockito.any(HttpServletRequest.class),
Mockito.any(HttpServletResponse.class),
Mockito.any(Object.class)))
.thenReturn(true);
Mockito.when(authUtil.getLoginUser()).thenReturn(null);
doNothing().when(authInitEvent).afterPropertiesSet();
// 请求部分
MvcResult mvcResult = mvc.perform(
post("/save")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(jsonString)
)
.andExpect(status().isOk())
.andDo(print())
.andReturn();
// 结果断言部分
String contentAsString = mvcResult.getResponse().getContentAsString();
Assert.assertNotNull(contentAsString);
Assert.assertEquals(200, JSONObject.parseObject(contentAsString).get("code"));
}
}
从上面的代码可以看出一个单元测试大概可以分为一下几部分:
- 注解部分
- Mock部分
- 请求部分
- 结果断言部分
注解部分
- @RunWith(SpringRunner.class)
@RunWith是Junit的注解,这个注解的作用是为了指定测试的运行环境,因为不同的框架会有不同的运行环境,
供其他框架实现。这里的SpringRunner.class,就是Spring框架的实现,提供了Spring容器的运行环境。
这样就可以让依赖自动注入了。
@SpringBootTest
该注解提供了两个属性用于配置:
webEnvironment:指定Web应用环境,它可以是以下值
MOCK:提供一个模拟的 Servlet 环境,内置的 Servlet 容器没有启动,配合可以与@AutoConfigureMockMvc
结合使用,用于基于 MockMvc 的应用程序测试。
RANDOM_PORT:加载一个 EmbeddedWebApplicationContext 并提供一个真正嵌入式的 Servlet 环境,
随机端口。
DEFINED_PORT:加载一个 EmbeddedWebApplicationContext 并提供一个真正嵌入式的 Servlet 环境,
默认端口 8080 或由配置文件指定。
NONE:使用 SpringApplication 加载 ApplicationContext,但不提供任何 servlet 环境。
classes:指定应用启动类,通常情况下无需设置,因为 SpringBoot 会自动搜索,直到找到
@SpringBootApplication 或 @SpringBootConfiguration 注解。
- Mock部分
Mock部分主要解决什么问题呢,比如某个接口你在测试的时候需要检测内存中的登录状态,
但是登录很麻烦,这时候你找到负责检测登录的类,可以Mock一个这个对象,编排他的行为,比如:调用这个对象的检测用户登录状态的方法时,你可以直接返回true。这个对象会自动代替,容器里面的相同的对象,进行依赖注入,从而当你在测试的时候系统调用用户登录状态检查时,会按照你编排的行为进行返回。