43.3.8 自动配置的Spring MVC测试

你可以使用@WebMvcTest检测Spring MVC控制器是否工作正常。该注解将自动配置Spring MVC设施,并且只扫描注解@Controller@ControllerAdvice@JsonComponentConverterGenericConverterFilterWebMvcConfigurerHandlerMethodArgumentResolver的bean。其他常规的@Component bean将不会被扫描。

如果你需要注册额外的组件,比如Jackson模块,你可以在你的测试上使用@Import来导入另外的配置类。

通常@WebMvcTest只限于单个控制器(controller)使用,并结合@MockBean以提供需要的协作者(collaborators)的mock实现。@WebMvcTest也会自动配置MockMvc,Mock MVC为快速测试MVC控制器提供了一种强大的方式,并且不需要启动一个完整的HTTP服务器。

使用@AutoConfigureMockMvc注解一个non-@WebMvcTest的类(比如@SpringBootTest)也可以自动配置MockMvc。下面的例子使用了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"));
    }

}

如果需要定义自定配置(auto-configuration)的元素(比如什么时候使用servlet filters),你可以使用@AutoConfigureMockMvc的属性。

如果你使用HtmlUnit或Selenium, 自动配置将提供一个HTMLUnit WebClient bean和/或WebDriver bean,以下是使用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放在一个特殊的“作用域”里。如果你不想要这个行为,你可以在你的WebDriver``@Bean定义上加上@Scope("singleton")

附录中可以查看@WebMvcTest开启的自动配置列表。

有时,光光编写Spring MVC测试是不够的。Spring Boot可以帮助你在实际的服务器上运行完整的端到端的测试

最后更新于