网站首页 > 技术文章 正文
下一篇[46.3.11、自动配置的Spring WebFlux测试]
英文原文:https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-testing.html
GitHub:https://github.com/jijicai/Spring/tree/master/spring-boot
46.3.6、使用 JMX
由于测试上下文框架缓存上下文,因此默认情况下禁用 JMX 以防止相同的组件在同一域上注册。如果此类测试需要访问 MBeanServer,请考虑将其标记为脏(dirty):
@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
public class SampleJmxTests {
@Autowired
private MBeanServer mBeanServer;
@Test
public void exampleTest() {
// ...
}
}
46.3.7、模拟和监视 Beans
运行测试时,有时需要在应用程序上下文中模拟某些组件。例如,你可能在某个远程服务上有一个 facade,在开发期间该服务不可用。当你希望模拟在实际环境中可能难以触发的故障时,模拟也很有用。
Spring Boot 包含一个 @MockBean 注解,该注解可用于为应用上下文中的 bean 定义 Mockito 模拟。可以使用注解添加新 bean 或替换单个现有 bean 定义。注解可直接用于测试类、测试中的字段或 @Configuration 类和字段。在字段上使用时,也会注入创建的模拟的实例。mock bean 在每个测试方法后自动重置。
注释:
如果你的测试使用 Spring Boot 的测试注解之一(如 @SpringBootTest),则会自动启用此功能。要将此功能与其他安排一起使用,必须显式添加监听器,如下面示例所示:
@TestExecutionListeners(MockitoTestExecutionListener.class)
以下示例使用模拟(mock)实现替换现有的 RemoteService bean:
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;
import org.springframework.test.context.junit4.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {
@MockBean
private RemoteService remoteService;
@Autowired
private Reverser reverser;
@Test
public void exampleTest() {
// RemoteService has been injected into the reverser bean
given(this.remoteService.someCall()).willReturn("mock");
String reverse = reverser.reverseSomeCall();
assertThat(reverse).isEqualTo("kcom");
}
}
注释:@MockBean 不能用于模拟在应用程序上下文刷新期间执行的 bean 的行为。执行测试时,应用程序上下文刷新已完成,配置模拟行为为时已晚。在这种情况下,我们建议使用 @Bean 方法来创建和配置模拟。
另外,你可以使用 @SpyBean 将任何现有的 bean 与 Mockito spy 打包在一起。有关详细信息,请参阅 Javadoc。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/api/org/springframework/boot/test/mock/mockito/SpyBean.html )
注释:虽然 Spring 的测试框架在测试之间缓存应用程序上下文,并为共享相同配置的测试重用上下文,但 @MockBean 或 @SpyBean 的使用会影响缓存键, 这很可能会增加上下文的数量。
提示:如果你使用 @SpyBean 来监视带有 @Cacheable 方法的 bean,该方法按名称引用参数,则你的应用程序必须使用 -parameters 进行编译。这确保参数名称在 bean 被监视后可用于缓存基础设施。
46.3.8、自动配置的测试
Spring Boot 的自动配置系统适用于应用程序,但有时对测试来说可能有点太多。这通常有助于只加载测试应用程序 “切片” 所需的配置部分。例如,你可能想要测试 Spring MVC 控制器是否正确映射 URLs,并且你不想在这些测试中涉及数据库调用,或者你可能想要测试 JPA 实体, 当这些测试运行时,你对 web 层不感兴趣。
spring-boot-test-autoconfigure 模块包含许多注解,可用于自动配置此类 “切片”。它们中的每一个都以类似的方式工作,提供一个加载 ApplicationContext 的 @…Test 注解和一个或多个可用于自定义自动配置设置的 @AutoConfigure… 注解。
注释:每个切片将组件扫描限制为适当的组件,并加载一组非常受限制的自动配置类。如果你需要排除其中一个,大多数 @…Test 注解都提供了一个 excludeAutoConfiguration 属性。或者,你可以使用 @ImportAutoConfiguration#exclude。
注释:不支持在一个测试中使用多个 @…Test 注解来包含多个 “切片”。如果你需要多个 “切片”,请选择其中一个 @…Test 注解,并手动包含其他 “切片” 的 @AutoConfigure… 注解。
提示:也可以将 @AutoConfigure… 注解与标准的 @SpringBootTest 注解一起使用。如果你对应用程序的“切片”不感兴趣,但需要一些自动配置的测试 bean,则可以使用此组合。
46.3.9、自动配置的 JSON 测试
要测试对象 JSON 序列化和反序列化是否按预期工作,可以使用 @JsonTest 注解。@JsonTest 自动配置可用的受支持 JSON 映射器,该映射器可以是以下库之一:
(1)Jackson ObjectMapper、任何 @JsonComponent bean 和任何 Jackson Module
(2)Gson
(3)Jsonb
提示:可以在附录中找到由 @JsonTest 启用的自动配置的列表。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/test-auto-configuration.html)
如果需要配置自动配置的元素,可以使用 @AutoConfigureJsonTesters 注解。
Spring Boot 包括基于 AssertJ 的帮助器,它们与 JSONAssert 和 JsonPath 库一起工作,检查 JSON 是否如预期的那样出现。JacksonTester、GsonTester、JsonbTester 和 BasicJsonTester 类可以分别用于 Jackson、Gson、Jsonb 和 String。使用 @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 方法。
如果你使用 Spring Boot 的基于 AssertJ 的帮助器在给定的 JSON 路径上对数字值进行断言,则可能无法根据类型使用 isEqualTo。相反,你可以使用 AssertJ 的 satisfies 来断言值与给定条件匹配。例如,下面的示例断言实际的数字是一个接近 0.15 的浮点值,偏移量为 0.01。
assertThat(json.write(message))
.extractingJsonPathNumberValue("@.test.numberValue")
.satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));
46.3.10、自动配置的 Spring MVC 测试
要测试 Spring MVC 控制器是否按预期工作,请使用 @WebMvcTest 注解。@WebMvcTest 自动配置 Spring MVC 基础设施,并将扫描的 bean 限制为 @Controller、@ControllerAdvice、@JsonComponent、Converter、GenericConverter、Filter、WebMVCConfiguer 和 HandlerMethodArgumentResolver。使用此注解时,不扫描常规 @Component bean。
提示:可以在附录中找到由 @WebMvcTest 启用的自动配置设置的列表。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/test-auto-configuration.html )
提示:如果你需要注册额外的组件,比如 Jackson Module,你可以在测试中使用 @Import 来导入额外的配置类。
通常,@WebMvcTest 仅限于单个控制器,并与 @MockBean 结合使用,为所需的协作者提供模拟实现。
@WebMvcTest 也会自动配置 MockMvc。Mock MVC 提供了一种强大的方法来快速测试 MVC 控制器,而不需要启动完整的 HTTP 服务器。
提示:你还可以在非 @WebMvcTest(如 @SpringBootTest)中自动配置 MockMvc,方法是使用 @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,自动配置还提供了一个 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 bean 放在一个特殊的“scope”中,以确保驱动程序在每次测试后退出,并注入新实例。如果你不想要这种行为,你可以将 @Scope("singleton") 添加到你的 WebDriver @Bean 定义中。
警告:Spring Boot 创建的 webDriver 范围将替换任何同名的用户定义范围。如果你定义自己的 webDriver 范围,你可能会发现在使用 @WebMvcTest 时它停止工作。
如果类路径上有Spring Security,@WebMvcTest 也将扫描 WebSecurityConfigurer bean。你可以使用 Spring Security 的测试支持,而不是完全禁用此类测试的安全性。有关如何使用 Spring Security 的 MockMvc 支持的更多详细信息,请参见第 80 章:使用 Spring Security 进行测试的操作指南部分。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/howto-use-test-with-spring-security.html )
提示:有时编写 Spring MVC 测试是不够的;Spring Boot 可以帮助你在实际的服务器上运行完整的端到端测试。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-with-running-server )
猜你喜欢
- 2024-10-17 使用 Spock 编写高效简洁的单元测试
- 2024-10-17 程序员有福了!万字长文带你掌握SpringBoot所提供的测试解决方案
- 2024-10-17 如何使用Spring Boot提供的测试工具和注解。
- 2024-10-17 单元测试实践(Spring-boot+Junbit5+Mockito)
- 2024-10-17 Spring云原生实战指南:8 弹性和可扩展性
- 2024-10-17 SpringBoot 太强了,这些优势你需要了解
- 2024-10-17 如何使用Spring Cloud Contract(如何使用朋友的山姆卡)
- 2024-10-17 Spring Boot 开发离不开这些注解,快来学习啦!
- 2024-10-17 Spring Boot中文参考指南46.3.11、自动配置的Spring WebFlux测试
- 2024-10-17 一台不容错过的Java单元测试代码“永动机”
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)