45.3.8自动配置的测试
Spring Boot的自动配置系统适用于应用程序,但有时对于测试来说有点太多了。通常,只需加载测试应用程序“切片”所需的配置部分。例
如,您可能希望测试Spring MVC控制器是否正确映射URL,并且您不希望在这些测试中涉及数据库调用,或者您可能想要测试JPA实体,并且您
对Web不感兴趣这些测试运行时的图层。
spring-boot-test-autoconfigure 模块包括许多可用于自动配置这种“切片”的注释。它们中的每一个都以类似的方式工作,提供 @… Test
注释,用于加载 ApplicationContext 和一个或多个 @AutoConfigure… 注释,可用于自定义自动配置设置。
每个切片都将组件扫描限制为适当的组件,并加载一组非常有限的自动配置类。如果您需要排除其中一个,则大多数 @… Test 注释
都会提供 excludeAutoConfiguration 属性。或者,您可以使用 @ImportAutoConfiguration#exclude 。
不支持在一次测试中使用多个 @… Test 注释包含多个“切片”。如果您需要多个“切片”,请选择 @… Test 注释之一并手动包含其
他“切片”的 @AutoConfigure… 注释。
也可以将 @AutoConfigure… 注释与标准 @SpringBootTest 注释一起使用。如果您对“切片”应用程序不感兴趣,但想要一些自
动配置的测试beans,则可以使用此组合。
45.3.9自动配置的JSON测试
要测试该对象JSON序列化和反序列化是否按预期工作,您可以使用 @JsonTest 注释。@JsonTest 自动配置可用的受支持的JSON映射器,它可
以是以下库之一:
Jackson ObjectMapper ,任何 @JsonComponent beans和任何Jackson Module s
Gson
Jsonb
可以在附录中找到 @JsonTest 启用的自动配置列表 。
如果需要配置自动配置的元素,可以使用 @AutoConfigureJsonTesters 注释。
Spring Boot包括基于AssertJ的助手,它们与JSONAssert和JsonPath库一起使用,以检查JSON是否按预期显
示。JacksonTester , GsonTester , JsonbTester 和 BasicJsonTester 类可分别用于Jackson,Gson,Jsonb和Strings。使
用 @JsonTest 时,测试类上的任何辅助字段都可以是 @Autowired 。以下示例显示了Jackson的测试类:
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.json.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.json.*;
import org.springframework.test.context.junit4.*;
import static org.assertj.core.api.Assertions.*;
@RunWith(SpringRunner.class)
@JsonTest
public class MyJsonTests {
@Autowired
private JacksonTester<VehicleDetails> json;
@Test
public void testSerialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
.isEqualTo("Honda");
}
@Test
public void testDeserialize() throws Exception {
String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
assertThat(this.json.parse(content))
.isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}
}
JSON帮助程序类也可以直接用于标准单元测试。为此,如果不使用 @JsonTest ,请在 @Before 方法中调用助手的 initFields
方法。
45.3.10自动配置的Spring MVC测试
要测试Spring MVC控制器是否按预期工作,请使用 @WebMvcTest 注释。@WebMvcTest 自动配置Spring MVC基础设施并将扫描beans限制
为 @Controller , @ControllerAdvice , @JsonComponent , Converter , GenericConverter , Filter , WebMvcConfigurer
和 HandlerMethodArgumentResolver 。使用此注释时,不会扫描常规 @Component beans。
可以在附录中找到 @WebMvcTest 启用的自动配置设置列表 。
如果您需要注册额外的组件,例如Jackson Module ,则可以在测试中使用 @Import 导入其他配置类。
通常, @WebMvcTest 仅限于一个控制器,并与 @MockBean 结合使用,为所需的协作者提供模拟实现。
@WebMvcTest 也自动配置 MockMvc 。Mock MVC提供了一种快速测试MVC控制器的强大方法,无需启动完整的HTTP服务器。
您还可以使用 @AutoConfigureMockMvc 对其进行注释,以非 @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"));
}
}
如果需要配置自动配置的元素(例如,应该应用servlet过滤器时),可以使用 @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将 WebDriver beans置于特殊的“范围”中,以确保驱动程序在每次测试后退出并注入新实例。如果您
不想要此行为,可以将 @Scope("singleton") 添加到 WebDriver @Bean 定义中。
Spring Boot创建的 webDriver 范围将替换任何用户定义的同名范围。如果您定义自己的 webDriver 范围,则在使
用 @WebMvcTest 时可能会发现它停止工作。
如果您在类路径上拥有Spring安全性, @WebMvcTest 也会扫描 WebSecurityConfigurer beans。您可以使用Spring安全性测试支持,而不是
完全禁用此类测试的安全性。有关如何使用Spring安全性 MockMvc 支持的更多详细信息,请参阅本章80,使用Spring安全性操作方法部分进行
测试。