使用MockMvc与SpringBootTest和使用WebMvcTest之间的区别

时间:2016-10-05 04:44:57

标签: spring-boot

我是Spring Boot的新手,我正在尝试了解SpringBoot中的测试工作原理。我对以下两个代码片段之间的区别有点困惑:

代码段1:

@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerApplicationTest {
    @Autowired    
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Greetings from Spring Boot!")));
    }
}

此测试使用@WebMvcTest注释,我相信它是用于特征切片测试,仅测试Web应用程序的Mvc层。

代码段2:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
    mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().string(equalTo("Greetings from Spring Boot!")));
    }
}

此测试使用@SpringBootTest注释和MockMvc。那么这与代码片段1有何不同?这有什么不同呢?

编辑: 添加代码片段3(在Spring文档中将其作为集成测试的示例)

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {

@LocalServerPort
private int port;

private URL base;

@Autowired
private TestRestTemplate template;

@Before
public void setUp() throws Exception {
    this.base = new URL("http://localhost:" + port + "/");
}

@Test
public void getHello() throws Exception {
    ResponseEntity<String> response = template.getForEntity(base.toString(),
            String.class);
    assertThat(response.getBody(), equalTo("Greetings from Spring Boot!"));
}
}

3 个答案:

答案 0 :(得分:53)

@SpringBootTest是一般测试注释。如果你正在寻找在1.4之前做同样事情的东西,那就是你应该使用的东西。它根本不使用切片,这意味着它将启动完整的应用程序上下文,而不是自定义组件扫描。

@WebMvcTest只会扫描您定义的控制器和MVC基础架构。而已。因此,如果您的控制器对服务层中的其他bean有一定的依赖性,那么在您自己加载该配置或为其提供模拟之前,测试将不会启动。这个速度要快得多,因为我们只加载你应用的一小部分。此注释使用切片。

Reading the doc也可能对你有帮助。

答案 1 :(得分:36)

@SpringBootTest 注释告诉Spring Boot去寻找一个主配置类(例如一个带@SpringBootApplication),并使用它来启动Spring应用程序上下文。 SpringBootTest加载完整的应用程序并注入所有可能很慢的bean。

@WebMvcTest - 用于测试控制器层,您需要使用Mock对象提供所需的剩余依赖项。

以下几点注释供您参考。

测试应用程序的切片 有时,您希望测试应用程序的简单“切片”,而不是自动配置整个应用程序。 Spring Boot 1.4引入了4个新的测试注释:

@WebMvcTest - for testing the controller layer
@JsonTest - for testing the JSON marshalling and unmarshalling
@DataJpaTest - for testing the repository layer
@RestClientTests - for testing REST clients

请参阅更多信息:https://spring.io/guides/gs/testing-web/

答案 2 :(得分:5)

MVC测试旨在仅覆盖应用程序的控制器部分。 HTTP请求和响应是模拟的,因此实际连接不会 创建。另一方面,当您使用@SpringBootTest时,所有 Web应用程序上下文的配置已加载,并且连接 正在通过真实的Web服务器。在这种情况下,您不会使用 MockMvc bean,但改为标准的Res​​tTemplate(或新的替代方法) TestRestTemplate)。

那么,我们什么时候应该选择一个? @WebMvcTest用于 从服务器端统一测试控制器。 @SpringBootTest,在 另一方面,当您想进行交互时,应该用于集成测试 来自客户端的应用程序。

这并不意味着您不能在@SpringBootTest中使用模拟;如果 您正在编写集成测试,但这仍然是必要的。在任何情况下, 最好不要仅将其用于简单控制器的单元测试。

源-通过Spring Boot学习微服务