41.3.7 自动配置的Spring MVC测试

要测试Spring MVC的控制器是否按预期工作,您可以使用@WebMvcTest注解。@WebMvcTest将自动配置Spring MVC的基础结构,并将被扫描的bean限制为@Controller@ControllerAdvice@JsonComponentFilterWebMvcConfigurer以及HandlerMethodArgumentResolver,而不会扫描一般的@Componentbean。

@WebMvcTest经常被限定到单个控制器上,并与@MockBean结合使用,为所需的协作对象提供模拟实现。

@WebMvcTest还自动配置MockMvc。MockMVC提供了一种快速测试MVC控制器的强大方式,无需启动完整的HTTP服务器。

您也可以在非@WebMvcTest环境(例如SpringBootTest)下,通过使用@AutoConfigureMockMvc注解自动配置MockMvc

import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    public void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
                .willReturn(new VehicleDetails("Honda", "Civic"));
        this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
                .andExpect(status().isOk()).andExpect(content().string("Honda Civic"));
    }

}

如果需要配置自动配置的元素(例如应当使用servlet过滤器时),您可以使用@AutoConfigureMockMvc注解中的属性。

如果您使用HtmlUnit或Selenium,自动配置还将提供WebClientbean和/或WebDriverbean。这是一个使用HtmlUnit的例子:

import com.gargoylesoftware.htmlunit.*;
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyHtmlUnitTests {

    @Autowired
    private WebClient webClient;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    public void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
                .willReturn(new VehicleDetails("Honda", "Civic"));
        HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
        assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
    }

}

默认情况下,Spring Boot会将WebDriverbean放在特殊的“scope”中,以确保每次测试后driver都会退出,并注入一个新的实例。如果不想如此,您可以在WebDriver@Bean定义中添加@Scope("singleton")

@WebMvcTest激活的自动配置列表可以在附录中找到。


书籍推荐