在编写Spring Boot程序时,由于使用了@Autowire进行自动注入,直接使用Junit编写测试会无法实现。这是因为没有启动对应的Spring容器,这些自动注入就无法进行。
要对Spring Boot程序进行测试,只能使用Spring提供的Spring Test,结合Junit进行测试。
1、maven依赖
除了添加Spring boot本身所需的依赖以外,还需要引入Spring Test相关的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2、简单示例
2.1、注入测试
测试时,如果没有启动Spring容器,会导致@Autowired失效,从而导致空指针异常。为了可以在测试用例中使用@Autowired,需要的注解有:
- @Runwith(SpringRunner.class)
- @SpringBootTest(classes = 当前Spring程序的入口类.class)
- @Autowired
//这两个注解表示是SpringTest
@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class Test {
@Autowired
ClassA classA;
@org.junit.Test
public void testAutowired(){
//查看注入是否成功
assertThat(classA).isNotNull();
}
}
2.2、web测试
在web项目中,我们经常需要模拟一个HTTP请求,看写的Controller是否表现正常。
2.2.1、启动Server进行测试
第一种方法是不只启动Spring容器,还启动Server,然后发出请求,验证回复。需要的注解有:
- @Runwith(SpringRunner.class)
- @SpringBootTest(classes = 当前Spring程序的入口类.class,webEnvironment = WebEnvironment.RANDOM_PORT)
- @LocalServerPort
- @Autowired
以及一个特殊的模板类:TestRestTemplate。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebTest {
//使用随机接口,避免接口被占用导致测试无法进行
@LocalServerPort
private int port;
//用于快速获取REST请求返回的对象
@Autowired
private TestRestTemplate restTemplate;
@Test
public void greetingShouldReturnDefaultMessage() throws Exception {
assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/",
String.class)).contains("Hello world");
}
}
类似的可以使用postForObject发送post请求。
2.2.2、不启动Server进行测试
第二种方法是只启动Spring容器,不启动Server,用一个“Mock MVC”单独测试web层。需要的注解有:
- @Runwith(SpringRunner.class)
- @SpringBootTest(classes = 当前Spring程序的入口类.class)
- @AutoConfigureMockMvc
- @Autowired
以及一个特殊的类:MockMvc。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@AutoConfigureMockMvc
public class MockMvcTest {
//用于模拟web层
@Autowired
private MockMvc mockMvc;
@Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc
//发送请求
.perform(MockMvcRequestBuilders.get("/"))
//打印响应信息
.andDo(MockMvcResultHandlers.print())
//判断响应状态是否==200
.andExpect(MockMvcResultMatchers.status().isOk())
//判断响应结果是否包含制定字符串
.andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("Hello world")));
}
}