添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
失落的弓箭  ·  排除在Spring ...·  1 周前    · 
俊秀的手套  ·  spring-test-examples/c ...·  1 周前    · 
完美的油条  ·  求解 ...·  1 月前    · 
路过的茴香  ·  VSTO ...·  4 月前    · 
性感的人字拖  ·  Forced Flowering in ...·  10 月前    · 
  • 1.4.1. ConfigFileApplicationContextInitializer
  • 1.4.2. TestPropertyValues
  • 1.4.3. OutputCapture
  • 1.4.4. TestRestTemplate
  • Spring Boot提供了许多实用程序和注解来帮助你测试应用程序。测试支持由两个模块提供: spring-boot-test 包含核心项, spring-boot-test-autoconfigure 支持测试的自动配置。

    1.1. 测试范围依赖性

    spring-boot-starter-test “Starter”(在测试 test scope 内)包含以下提供的库:

    通常,你需要超越单元测试并开始集成测试(使用Spring ApplicationContext )。能够在不需要部署应用程序或需要连接到其他基础设施 的情况下执行集成测试非常有用。

    Spring框架包含一个用于此类集成测试的专用测试模块。你可以直接声明该依赖项: org.springframework:spring-test 或使用 spring-boot-starter-test “Starter”来传递它。

    如果你之前没有使用过Spring测试模块,那么首先应阅读 Spring框架参考文档 的相关部分。

    1.3. 测试Spring Boot应用程序

    Spring Boot应用程序是一个Spring ApplicationContext ,因此除了通常使用的Spring上下文之外,还没有什么特别的东西可以用来测试它。

    Spring Boot提供 @SpringBootTest 注解,当你需要Spring Boot功能时,它可以用作标准 spring-test @ContextConfiguration 注解的替代方法。注解通过 SpringApplication 创建测试中使用的 ApplicationContext 来工作 。除了 @SpringBootTest 之外,还提供了许多其他注解来测试应用程序的 更具体的切片

    MOCK (默认):加载Web ApplicationContext 并提供模拟Web环境。使用此批注时,不会启动嵌入式服务器。 如果类路径上没有Web环境,则此模式将透明地回退到创建常规非Web ApplicationContext 。它可以与 @AutoConfigureMockMvc @AutoConfigureWebTestClient 结合使用,以进行基于模拟的Web应用程序测试。

    RANDOM_PORT :加载 WebServerApplicationContext 并提供真实的Web环境。嵌入式服务器启动并侦听在随机端口上。

    DEFINED_PORT : 加载 WebServerApplicationContext 并提供真实的Web环境。嵌入式服务器启动并侦听在指定端口上 (来自你的 application.properties )或默认端口 8080

    NONE :使用 SpringApplication 加载 ApplicationContext 但不提供任何Web环境(模拟或其他)。

    如果你的测试是 @Transactional ,则默认情况下会在每个测试方法的末尾回滚事务。但是,如果使用 RANDOM_PORT DEFINED_PORT 这种配置隐式提供了一个真正的servlet环境,HTTP客户端和服务器会在不同的线程中运行,因此在单独的事务中运行。在这种情况下, 在服务器上启动的任何事务都不会回滚。

    1.3.1. 检测Web应用程序类型

    如果Spring MVC可用,则配置基于MVC的常规应用程序上下文。如果你只有Spring WebFlux,我们将检测到并配置基于WebFlux的应用程序上下文。

    如果两者都存在,则Spring MVC优先。如果要在此方案中测试响应式Web应用程序,则必须设置 spring.main.web-application-type 属性:

    @RunWith(SpringRunner.class)
    @SpringBootTest(properties = "spring.main.web-application-type=reactive")
    public class MyWebFluxTests { ... }

    1.3.2. 检测测试配置

    如果你熟悉Spring Test框架,则可能习惯使用 @ContextConfiguration(classes=…​) 来指定要加载的Spring @Configuration 。 或者,你可能经常在测试中使用嵌套的 @Configuration 类。

    在测试Spring Boot应用程序时,通常不需要这样做。只要你没有明确定义,Spring Boot的 @*Test 注解会自动搜索你的主要配置。

    搜索算法从包含测试的包开始工作,直到找到使用 @SpringBootApplication @SpringBootConfiguration 注解的类。 只要你以合理的方式 结构化代码 ,通常就会自动找到主要配置。

    如果你的应用程序使用组件扫描(例如,如果你使用 @SpringBootApplication @ComponentScan ), 你可能会发现仅为特定测试创建的顶级配置类会意外地在任何地方被拾取应用。

    如前所述 @TestConfiguration 可用于测试的内部类以自定义主要配置。当置于顶级类时, @TestConfiguration 指示不应通过扫描拾取 src/test/java 中的类。 然后,你可以在需要的位置显式导入该类,如以下示例所示:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @Import(MyTestsConfiguration.class)
    public class MyTests {
    	@Test
    	public void exampleTest() {
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class MockMvcExampleTests {
    	@Autowired
    	private MockMvc mvc;
    	@Test
    	public void exampleTest() throws Exception {
    		this.mvc.perform(get("/")).andExpect(status().isOk())
    				.andExpect(content().string("Hello World"));
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.reactive.server.WebTestClient;
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureWebTestClient
    public class MockWebTestClientExampleTests {
    	@Autowired
    	private WebTestClient webClient;
    	@Test
    	public void exampleTest() {
    		this.webClient.get().uri("/").exchange().expectStatus().isOk()
    				.expectBody(String.class).isEqualTo("Hello World");
    

    1.3.5. 使用正在运行的服务器进行测试

    如果你需要启动完整运行的服务器,我们建议你使用随机端口。如果使用 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT), 则每次运行测试时都会随机选择一个可用端口。

    @LocalServerPort 注解可用于注入测试中 实际使用的随机端口。 为方便起见,需要对启动的服务器进行REST调用的测试还可以 @Autowire WebTestClient, 它解析了与正在运行的服务器的相对链接,并附带了用于验证响应的专用API,如以下示例所示:

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.reactive.server.WebTestClient;
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    public class RandomPortWebTestClientExampleTests {
    	@Autowired
    	private WebTestClient webClient;
    	@Test
    	public void exampleTest() {
    		this.webClient.get().uri("/").exchange().expectStatus().isOk()
    				.expectBody(String.class).isEqualTo("Hello World");
    

    此设置需要类路径上有 spring-webflux。如果你不能或不愿添加webflux,Spring Boot还提供了一个 TestRestTemplate 工具:

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
    import org.springframework.boot.test.web.client.TestRestTemplate;
    import org.springframework.test.context.junit4.SpringRunner;
    import static org.assertj.core.api.Assertions.assertThat;
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    public class RandomPortTestRestTemplateExampleTests {
    	@Autowired
    	private TestRestTemplate restTemplate;
    	@Test
    	public void exampleTest() {
    		String body = this.restTemplate.getForObject("/", String.class);
    		assertThat(body).isEqualTo("Hello World");
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(properties = "spring.jmx.enabled=true")
    @DirtiesContext
    public class SampleJmxTests {
    	@Autowired
    	private MBeanServer mBeanServer;
    	@Test
    	public void exampleTest() {
    		// ...
    

    Spring Boot包含一个 @MockBean 注解,可用于为 ApplicationContext 中的bean定义Mockito模拟。 你可以使用该注解添加新bean或替换单个现有bean定义。该注解可以直接用于测试类,测试中的字段或 @Configuration 类和字段。 在字段上使用时,也会注入创建的模拟实例。每个测试方法结束后,模拟Bean都会自动重置。

    如果你的测试使用Spring Boot的测试注解之一(例如 @SpringBootTest),则会自动启用此功能。 要将此特性用于不同的安排,必须显式地添加侦听器,如下面的示例所示:

    @TestExecutionListeners(MockitoTestExecutionListener.class)

    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已注入Reverser bean
    		given(this.remoteService.someCall()).willReturn("mock");
    		String reverse = reverser.reverseSomeCall();
    		assertThat(reverse).isEqualTo("kcom");
    

    此外,你可以使用 @SpyBean 将任何现有bean包装为Mockito间谍。有关详细信息,请参阅 Javadoc

    Spring Boot的自动配置系统适用于应用程序,但有时对于测试来说有点太多了。通常,只需加载测试应用程序“切片”所需的配置部分。 例如,你可能希望测试Spring MVC控制器是否正确映射URL,并且你不希望在这些测试中涉及数据库调用,或者你可能想要测试JPA实体, 并且你对Web层测试运行不感兴趣。

    spring-boot-test-autoconfigure 模块包括许多可用于自动配置这种“切片”的注解。它们中的每一个都以类似的方式工作, 提供一个 @…​Test 注解,用于加载 ApplicationContext 和一个或多个 @AutoConfigure…​ 注解,可用于自定义自动配置设置。

    Spring Boot包括基于AssertJ的辅助类,它们与JSONAssert和JsonPath库一起使用,以检查JSON是否按预期显示。 JacksonTesterGsonTesterJsonbTesterBasicJsonTester 类可分别用于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");
    		// 断言设置了一个与测试处于相同的包中 `.json` 文件
    		assertThat(this.json.write(details)).isEqualToJson("expected.json");
    		// 或者使用基于JSON路径的断言
    		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");
    

    1.3.10. 自动配置Spring MVC测试

    要测试Spring MVC控制器是否按预期工作,请使用 @WebMvcTest 注解。@WebMvcTest 自动配置Spring MVC基础设施并将扫描的bean限制为 @Controller@ControllerAdvice@JsonComponentConverterGenericConverterFilterWebMvcConfigurerHandlerMethodArgumentResolver。使用此注解时,不会扫描常规 @Component bean。

    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"));
    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 Security,@WebMvcTest 也将扫描 WebSecurityConfigurer bean。你可以使用Spring Security的测试支持, 而不是完全禁用此类测试的安全性。有关如何使用Spring Security的 MockMvc 支持的更多详细信息,请参见第80章 使用Spring Security测试方法部分。

    1.3.11. 自动配置Spring WebFlux测试

    要测试Spring WebFlux控制器是否按预期工作,可以使用 @WebFluxTest 注解。@WebFluxTest 自动配置Spring WebFlux基础设施并将扫描的 bean限制为 @Controller@ControllerAdvice@JsonComponentConverterGenericConverterWebFluxConfigurer。 使用 @WebFluxTest 注解时,不会扫描常规 @Component bean。

    import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; @RunWith(SpringRunner.class) @WebFluxTest(UserVehicleController.class) public class MyControllerTests { @Autowired private WebTestClient webClient; @MockBean private UserVehicleService userVehicleService; @Test public void testExample() throws Exception { given(this.userVehicleService.getVehicleDetails("sboot")) .willReturn(new VehicleDetails("Honda", "Civic")); this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN) .exchange() .expectStatus().isOk() .expectBody(String.class).isEqualTo("Honda Civic");
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    @RunWith(SpringRunner.class)
    @DataJpaTest
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public class ExampleNonTransactionalTests {
    

    Data JPA测试还可以注入 TestEntityManagerbean, 它提供了专门为测试设计的标准JPA EntityManager 的替代方法。如果要在 @DataJpaTest 实例之外使用 TestEntityManager, 还可以使用 @AutoConfigureTestEntityManager 注解。如果需要,还可以使用 JdbcTemplate。 以下示例显示如何使用的 @DataJpaTest 注解:

    import org.junit.*;
    import org.junit.runner.*;
    import org.springframework.boot.test.autoconfigure.orm.jpa.*;
    import static org.assertj.core.api.Assertions.*;
    @RunWith(SpringRunner.class)
    @DataJpaTest
    public class ExampleRepositoryTests {
    	@Autowired
    	private TestEntityManager entityManager;
    	@Autowired
    	private UserRepository repository;
    	@Test
    	public void testExample() throws Exception {
    		this.entityManager.persist(new User("sboot", "1234"));
    		User user = this.repository.findByUsername("sboot");
    		assertThat(user.getUsername()).isEqualTo("sboot");
    		assertThat(user.getVin()).isEqualTo("1234");
    

    内存中嵌入式数据库通常适用于测试,因为它们速度快且不需要任何安装。但是,如果你更喜欢对真实数据库运行测试, 则可以使用 @AutoConfigureTestDatabase 注解配置,如以下示例所示:

    @RunWith(SpringRunner.class)
    @DataJpaTest
    @AutoConfigureTestDatabase(replace=Replace.NONE)
    public class ExampleRepositoryTests {
    	// ...
    

    1.3.13. 自动配置JDBC测试

    @JdbcTest 类似于 @DataJpaTest,但适用于仅需要 DataSource 且不使用Spring Data JDBC的测试。 默认情况下,它配置内存中嵌入式数据库和 JdbcTemplate。常规 @Component bean不会被加载到 ApplicationContext 中。

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    @RunWith(SpringRunner.class)
    @JdbcTest
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public class ExampleNonTransactionalTests {
    

    如果你希望测试针对真实数据库运行,则可以使用与 DataJpaTest 相同的方式使用 @AutoConfigureTestDatabase 注解。 (请参阅自动配置Data JPA测试部分)

    1.3.14. 自动配置数据JDBC测试

    @DataJdbcTest 类似于 @JdbcTest,但适用于使用Spring Data JDBC存储库的测试。默认情况下,它配置内存中嵌入式数据库, JdbcTemplate 和Spring Data JDBC存储库。常规 @Component bean不会被加载到 ApplicationContext 中。

    默认情况下,Data JDBC测试是事务性的,并在每次测试结束时回滚。有关更多详细信息,请参阅Spring框架参考指南中的 相关部分。 如果这不是你想要的,你可以像在JDBC示例中显示的那样为测试或整个类禁用事务管理。

    如果你希望测试针对真实数据库运行,则可以使用与 DataJpaTest 相同的方式使用 @AutoConfigureTestDatabase 注解。 (请参阅自动配置Data JPA测试部分)

    1.3.15. 自动配置jOOQ测试

    你可以像 @JdbcTest 一样使用 @JooqTest 但是它仅用于jOOQ相关的测试。由于jOOQ严重依赖于与数据库schema相对应的基于Java的schema, 因此会使用现有的 DataSource。如果要将其替换为内存数据库,可以使用 @AutoConfigureTestDatabase 覆盖这些设置。 (有关在Spring Boot中使用jOOQ的更多信息,请参阅本章前面的 使用jOOQ) 常规 @Component bean不会被加载到 ApplicationContext 中。

    import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.autoconfigure.jooq.JooqTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @JooqTest public class ExampleJooqTests { @Autowired private DSLContext dslContext;

    默认情况下,JOOQ测试是事务性的,并在每次测试结束时回滚。如果这不是你想要的,你可以像 在JDBC示例中显示的那样为测试或整个类禁用事务管理。

    1.3.16. 自动配置Data MongoDB测试

    你可以使用 @DataMongoTest 来测试MongoDB应用程序。默认情况下,它配置内存中嵌入的MongoDB(如果可用),配置 MongoTemplate, 扫描 @Document 类,以及配置Spring Data MongoDB存储库。常规 @Component bean不会被加载到 ApplicationContext 中。 (有关将MongoDB与Spring Boot一起使用的更多信息,请参阅本章前面的 MongoDB部分)

    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.test.context.junit4.SpringRunner;
    @RunWith(SpringRunner.class)
    @DataMongoTest
    public class ExampleDataMongoTests {
    	@Autowired
    	private MongoTemplate mongoTemplate;
    

    内存中嵌入式MongoDB通常适用于测试,因为它速度快,不需要任何开发人员安装。但是,如果你更喜欢对真正的MongoDB服务器运行测试, 则应排除嵌入式MongoDB自动配置,如以下示例所示:

    import org.junit.runner.RunWith;
    import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
    import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
    import org.springframework.test.context.junit4.SpringRunner;
    @RunWith(SpringRunner.class)
    @DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
    public class ExampleDataMongoNonEmbeddedTests {
    

    1.3.17. 自动配置Data Neo4j测试

    你可以使用 @DataNeo4jTest 来测试Neo4j应用程序。默认情况下,它使用内存中嵌入式Neo4j(如果嵌入式驱动程序可用), 扫描 @NodeEntity 类,并配置Spring Data Neo4j存储库。常规 @Component bean不会被加载到 ApplicationContext 中。 (有关在Spring Boot中使用Neo4J的更多信息,请参阅本章前面的 使用Neo4j

    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
    import org.springframework.test.context.junit4.SpringRunner;
    @RunWith(SpringRunner.class)
    @DataNeo4jTest
    public class ExampleDataNeo4jTests {
    	@Autowired
    	private YourRepository repository;
    

    默认情况下,Data Neo4j测试是事务性的,并在每次测试结束时回滚。有关更多详细信息,请参阅Spring框架参考指南中的 相关部分。 如果这不是你想要的,你可以像下例所示为测试或整个类禁用事务管理。

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    @RunWith(SpringRunner.class)
    @DataNeo4jTest
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public class ExampleNonTransactionalTests {
    

    1.3.18. 自动配置Data Redis测试

    你可以使用 @DataRedisTest 来测试Redis应用程序。默认情况下,它会扫描 @RedisHash 类并配置Spring Data Redis存储库。 常规 @Component bean不会被加载到 ApplicationContext 中。 (有关将Redis与Spring Boot一起使用的更多信息,请参阅本章前面的 Redis部分)

    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest;
    import org.springframework.test.context.junit4.SpringRunner;
    @RunWith(SpringRunner.class)
    @DataRedisTest
    public class ExampleDataRedisTests {
    	@Autowired
    	private YourRepository repository;
    

    1.3.19. 自动配置Data LDAP测试

    你可以使用 @DataLdapTest 来测试LDAP应用程序。默认情况下,它配置内存中嵌入式LDAP(如果可用),配置 LdapTemplate, 扫描 @Entry 类,以及配置Spring Data LDAP存储库。常规 @Component bean不会被加载到 ApplicationContext 中。 (有关在Spring Boot中使用LDAP的更多信息,请参阅本章前面的 使用LDAP

    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
    import org.springframework.ldap.core.LdapTemplate;
    import org.springframework.test.context.junit4.SpringRunner;
    @RunWith(SpringRunner.class)
    @DataLdapTest
    public class ExampleDataLdapTests {
    	@Autowired
    	private LdapTemplate ldapTemplate;
    

    内存中嵌入式LDAP通常适用于测试,因为它速度快,不需要任何开发人员安装。 但是,如果你希望针对真实LDAP服务器运行测试,则应排除嵌入式LDAP自动配置,如以下示例所示:

    import org.junit.runner.RunWith;
    import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration;
    import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
    import org.springframework.test.context.junit4.SpringRunner;
    @RunWith(SpringRunner.class)
    @DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class)
    public class ExampleDataLdapNonEmbeddedTests {
    
    @RunWith(SpringRunner.class)
    @RestClientTest(RemoteVehicleDetailsService.class)
    public class ExampleRestClientTest {
    	@Autowired
    	private RemoteVehicleDetailsService service;
    	@Autowired
    	private MockRestServiceServer server;
    	@Test
    	public void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails()
    			throws Exception {
    		this.server.expect(requestTo("/greet/details"))
    				.andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
    		String greeting = this.service.callRestService();
    		assertThat(greeting).isEqualTo("hello");
    

    1.3.21. 自动配置Spring REST Docs测试

    你可以使用 @AutoConfigureRestDocs 注解在Mock MVC,REST Assured或WebTestClient的测试中使用 Spring REST Docs。它移除了Spring REST Docs中JUnit rule的需要。

    @AutoConfigureRestDocs 可用于覆盖默认输出目录(如果你使用的是Maven,则为 target/generated-snippets 或 如果你使用的是Graven,则为 build/generated-snippets)。它还可用于配置出现在任何已记录的URI中的host, scheme和port。

    使用Mock MVC自动配置Spring REST Docs测试

    @AutoConfigureRestDocs 自定义 MockMvc bean以使用Spring REST Docs。你可以使用 @Autowired 注入它,并在使用Mock MVC 和Spring REST Docs时在测试中使用它,如以下示例所示:

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    import org.springframework.http.MediaType;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
    @RunWith(SpringRunner.class)
    @WebMvcTest(UserController.class)
    @AutoConfigureRestDocs
    public class UserDocumentationTests {
    	@Autowired
    	private MockMvc mvc;
    	@Test
    	public void listUsers() throws Exception {
    		this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
    				.andExpect(status().isOk())
    				.andDo(document("list-users"));
    

    如果你需要更多对Spring REST Docs配置的控制,而不仅仅满足于 @AutoConfigureRestDocs 的属性, 则可以使用 RestDocsMockMvcConfigurationCustomizer bean,如以下示例所示:

    @TestConfiguration
    static class CustomizationConfiguration
    		implements RestDocsMockMvcConfigurationCustomizer {
    	@Override
    	public void customize(MockMvcRestDocumentationConfigurer configurer) {
    		configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    

    如果要对参数化输出目录使用Spring REST Docs支持,可以创建 RestDocumentationResultHandler bean。 自动配置使用此结果处理程序调用 alwaysDo,从而使每个 MockMvc 调用自动生成默认代码段。 以下示例显示何如定义 RestDocumentationResultHandler

    @TestConfiguration
    static class ResultHandlerConfiguration {
    	@Bean
    	public RestDocumentationResultHandler restDocumentation() {
    		return MockMvcRestDocumentation.document("{method-name}");
    
    使用REST Assured自动配置Spring REST Docs测试

    @AutoConfigureRestDocs` 生成一个 RequestSpecification bean,预先配置为使用Spring REST Docs,可用于你的测试。 你可以使用 @Autowired 注入它并在测试中使用它,就像使用REST Assured和Spring REST Doc时一样,如下例所示:

    import io.restassured.specification.RequestSpecification;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
    import org.springframework.boot.web.server.LocalServerPort;
    import org.springframework.test.context.junit4.SpringRunner;
    import static io.restassured.RestAssured.given;
    import static org.hamcrest.CoreMatchers.is;
    import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document;
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    @AutoConfigureRestDocs
    public class UserDocumentationTests {
    	@LocalServerPort
    	private int port;
    	@Autowired
    	private RequestSpecification documentationSpec;
    	@Test
    	public void listUsers() {
    		given(this.documentationSpec).filter(document("list-users")).when()
    				.port(this.port).get("/").then().assertThat().statusCode(is(200));
    

    如果你需要对Spring REST Docs配置的更多控制,而不仅仅是 @AutoConfigureRestDocs 的属性, 则可以使用 RestDocsRestAssuredConfigurationCustomizer bean,如以下示例所示:

    @TestConfiguration
    public static class CustomizationConfiguration
    		implements RestDocsRestAssuredConfigurationCustomizer {
    	@Override
    	public void customize(RestAssuredRestDocumentationConfigurer configurer) {
    		configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    
    @RunWith(SpringRunner.class)
    @JdbcTest
    @ImportAutoConfiguration(IntegrationAutoConfiguration.class)
    public class ExampleJdbcTests {
    

    1.3.24. 使用Spock测试Spring Boot应用程序

    如果你希望使用Spock测试Spring Boot应用程序,你应该将Spock spock-spring 模块的依赖项添加到应用程序的构建中。 spock-spring 集成Spring测试框架到Spock中。建议你使用Spock 1.2或更高版本,以便从Spock的Spring框架和Spring Boot 集成的许多改进中受益。有关更多详细信息,请参阅 Spock Spring模块的文档

    1.4.1. ConfigFileApplicationContextInitializer

    ConfigFileApplicationContextInitializer 是一个 ApplicationContextInitializer,你可以将其应用于测试以加载Spring Boot application.properties 文件。当你不需要 @SpringBootTest 提供的全套功能时,可以使用它,如以下示例所示:

    仅使用 ConfigFileApplicationContextInitializer 不支持 @Value("${…​}") 注入。 它唯一的工作是确保将 application.properties 文件加载到Spring的环境中。 对于 @Value 支持,你需要另外配置 PropertySourcesPlaceholderConfigurer 或使用 @SpringBootTest 它会自动为你配置一个。

    1.4.2. TestPropertyValues

    TestPropertyValues 允许你快速向 ConfigurableEnvironmentConfigurableApplicationContext 添加属性。 你可以使用 key=value 字符串调用它,如下所示:

    TestPropertyValues.of("org=Spring", "name=Boot").applyTo(env);

    1.4.3. OutputCapture

    OutputCapture 是一个JUnit Rule,可用于捕获 System.outSystem.err 输出。你可以将捕获声明为 @Rule, 然后使用 toString() 进行断言,如下所示:

    import org.junit.Rule;
    import org.junit.Test;
    import org.springframework.boot.test.rule.OutputCapture;
    import static org.hamcrest.Matchers.*;
    import static org.junit.Assert.*;
    public class MyTest {
    	@Rule
    	public OutputCapture capture = new OutputCapture();
    	@Test
    	public void testName() throws Exception {
    		System.out.println("Hello World!");
    		assertThat(capture.toString(), containsString("World"));
    

    TestRestTemplate 是Spring的 RestTemplate 的一种便利替代品,可用于集成测试。你可以获得一个vanilla模板或一个发送基本HTTP 身份验证(使用用户名和密码)的模板。在任何一种情况下,模板都以一种测试友好的方式运行,不会在服务器端错误上抛出异常。 建议(但不是强制性的)使用Apache HTTP Client(版本4.3.2或更高版本)。如果你在类路径上有这个,则 TestRestTemplate 通过适当地配置客户端来响应。如果你确实使用了Apache的HTTP客户端,则会启用一些额外的测试友好功能:

    @Test public void testRequest() throws Exception { HttpHeaders headers = this.template.getForEntity( "http://myhost.example.com/example", String.class).getHeaders(); assertThat(headers.getLocation()).hasHost("other.example.com");

    或者,如果将 @SpringBootTest 注解与 WebEnvironment.RANDOM_PORTWebEnvironment.DEFINED_PORT 一起使用, 则可以注入已完全配置的 TestRestTemplate 并开始使用它。如有必要,可以通过 RestTemplateBuilder bean应用其他自定义。 任何未指定主机和端口的URL都会自动连接到嵌入式服务器,如以下示例所示:

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    public class SampleWebClientTests {
    	@Autowired
    	private TestRestTemplate template;
    	@Test
    	public void testRequest() {
    		HttpHeaders headers = this.template.getForEntity("/example", String.class)
    				.getHeaders();
    		assertThat(headers.getLocation()).hasHost("other.example.com");
    	@TestConfiguration
    	static class Config {
    		@Bean
    		public RestTemplateBuilder restTemplateBuilder() {
    			return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1))
    					.setReadTimeout(Duration.ofSeconds(1));