领先一步
VMware 提供培训和认证,以加快您的进度。
了解更多Spring Boot 1.4 包含对测试支持的重大改进,其中一项功能是测试切片。我想借这篇博客文章的机会,进一步解释它是什么以及如何轻松创建您自己的切片。
测试切片是关于分割为您的测试创建的ApplicationContext
。通常,如果您想使用MockMvc
测试控制器,您肯定不想费心处理数据层。相反,您可能希望模拟控制器使用的服务,并验证所有与 Web 相关的交互是否按预期工作。这可以在下面的示例中概括
@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class UserVehicleControllerTests {
@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"));
}
}
@WebMvcTest
是 Spring Boot 1.4 中的 Web 测试切片。当它存在时,您指示 Spring Boot 需要 Web 环境,并且只应实例化指定的控制器。因为它了解测试的性质,所以它可以为您做出更多明智的决策(例如,自动配置MockMvc
,这样剩下的就是注入它)。此外,您的控制器依赖于UserVehicleService
,因此启动上下文会导致失败,因为ApplicationContext
不知道它(记住,只有 Web 基础设施和UserVehicleController
是已知的)。@MockBean
在这里用于注册UserVehicleService
模拟,以便可以将其透明地注入控制器。
现在让我们看一下实现,以便更好地理解 Spring Boot 如何为您管理它。我们的第一步是@WebMvcTest
(为简洁起见,删除了@Target
等)
@BootstrapWith(WebMvcTestContextBootstrapper.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(WebMvcTypeExcludeFilter.class)
@AutoConfigureCache
@AutoConfigureWebMvc
@AutoConfigureMockMvc
@ImportAutoConfiguration
public @interface WebMvcTest { ... }
此声明可以分为三个部分
Spring Boot 1.4 现在定义了一个spring-boot-test-autoconfigure
模块,该模块提供了一组与测试相关的自动配置。这些自动配置是可组合的,可以帮助您轻松创建自己的基础设施。
回到@WebMvcTest
,我们首先要做的就是禁用默认的自动配置:OverrideAutoConfiguration
就是这样做的。由于默认的自动配置现在已禁用,您必须选择要包含的相关自动配置。三个AutoConfigure
注解为我们做了这件事:它们确保 Web 环境可用,MockMvc
已配置,并且可用的缓存管理器为空操作。让我们看一下AutoconfigureMockMvc
的摘录
@ImportAutoConfiguration
@PropertyMapping("spring.test.mockmvc")
public @interface AutoConfigureMockMvc {
boolean addFilters() default true;
@PropertyMapping("webclient.enabled")
boolean webClientEnabled() default true;
...
}
@ImportAutoConfiguration
是一个注解,它列出了应该包含的自动配置。或者,您可以使用注解的全限定名作为键,在META-INF/spring.factories
中提供列表。这就是为AutoConfigureMockMvc
定义的内容
org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc=\
org.s.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration,\
org.s.boot.test.autoconfigure.web.servlet.MockMvcSecurityAutoConfiguration,\
org.s.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration,\
org.s.boot.test.autoconfigure.web.servlet.MockMvcWebDriverAutoConfiguration
您明白了:每个注解都带来一些自动配置,您可以根据需要组合它们。您会注意到WebMvcTest
也有一个ImportAutoConfiguration
,但spring.factories
中没有它的条目。Spring Boot 将扫描类路径中的所有spring.factories
,并在必要时合并内容。如果您的模块想要向@WebMvcTest
(或@AutoConfigureMockMvc
)添加其他行为,只需要创建一个META-INF/spring.factories
并注册额外的自动配置类。您还可以使用@AutoconfigureBefore
和@AutoconfigureAfter
来排序它们。
测试自动配置通常是可配置的:类级别的@PropertyMapping
注解将注解的属性映射到Environment
,以便自动配置代码可以提取值并相应地调整配置。我们可以看到上面的webClientEnabled
属性在自动配置中被透明地使用
@ConditionalOnProperty(prefix = "spring.test.mockmvc.webclient",
name = "enabled", matchIfMissing = true)
public class MockMvcWebClientAutoConfiguration { ... }
TypeExcludeFilters
是一种调整类路径扫描的方法。在@WebMvcTest
的情况下,我们只将包含某些与 Web 相关的组件并忽略所有其他组件。这非常强大,因为您可以像往常一样使用类路径扫描,并且只包含切片所需的内容。
最后,新的测试引导确保识别项目中使用@SpringBootApplication
注解的类(除非指定了一个)。这是一个不错的默认值,因为您不再需要指定它,并且类路径扫描默认情况下是正确的。
基于这些知识,创建您自己的切片实际上非常容易。这种切片的一个示例可能是新的DataJdbcTest
,它类似于DataJpaTest
的切片,它只配置JdbcTemplate
而不使用JPA。如果您想立即使用代码,请查看github 存储库以了解更多详细信息。
我们的第一步是创建@AutoconfigureDataJdbc
package com.example.test.autoconfigure.jdbc;
import java.lang.annotation.*;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ImportAutoConfiguration
public @interface AutoconfigureDataJdbc {
}
并注册此注解存在时要应用的相关自动配置。再次,创建一个META-INF/spring.factories
资源
com.example.test.autoconfigure.jdbc.AutoconfigureDataJdbc=\
org.s.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.s.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.s.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.s.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.s.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.s.boot.autoconfigure.transaction.TransactionAutoConfiguration
一旦这个可重用的基础设施到位,您可以创建您的测试切片,并简单地指定您需要一个数据库和 jdbc
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(DataJdbcTypeExcludeFilter.class)
@Transactional
@AutoConfigureCache
@AutoconfigureDataJdbc
@AutoConfigureTestDatabase
@ImportAutoConfiguration
public @interface DataJdbcTest { }
DataJdbcTypeExcludeFilter
确保排除所有其他服务,因为此类测试默认情况下不应该需要任何您的 bean。它可以改进为允许将服务定义为注解的参数,这与WebMvcTest
添加指定的控制器非常相似。
完成此操作后,您只需要添加您的注解,您的JdbcTemplate
就会为您使用测试数据库自动配置。
@RunWith(SpringRunner.class)
@DataJdbcTest
public class DataJdbcSampleTests {
@Autowired
private JdbcTemplate jdbcTemplate;
...
}
Spring Boot 1.4 将自动配置引入您的测试,并允许您轻松组合您自己的测试注解。在本文中,我们看到了WebMvcTest
的工作原理以及如何创建您自己的“jdbc”切片。我们实际上正在考虑在下一个版本中添加该注解,因此请继续提供反馈!