45. Testing

Spring Boot 提供了许多 Util 和 Comments,可以在测试应用程序时提供帮助。测试支持由两个模块提供:spring-boot-test包含核心项目,而spring-boot-test-autoconfigure支持自动配置测试。

大多数开发人员使用spring-boot-starter-test“Starter 程序”,该程序同时导入 Spring Boot 测试模块以及 JUnit,AssertJ,Hamcrest 和许多其他有用的库。

45.1 测试范围依赖性

spring-boot-starter-test“Starter”(位于test scope中)包含以下提供的库:

  • JUnit:用于对 Java 应用程序进行单元测试的实际标准。

  • Spring Test和 Spring Boot 测试:对 Spring Boot 应用程序的 Util 和集成测试支持。

  • AssertJ:流畅的 assert 库。

  • Hamcrest:匹配器对象库(也称为约束或谓词)。

  • Mockito:Java 模拟框架。

  • JSONassert:JSON 的 assert 库。

  • JsonPath:JSON 的 XPath。

通常,我们发现这些通用库在编写测试时很有用。如果这些库不满足您的需求,则可以添加自己的其他测试依赖项。

45.2 测试 Spring 应用程序

依赖注入的主要优点之一是,它应该使您的代码更易于进行单元测试。您可以使用new运算符实例化对象,而无需使用 Spring。您也可以使用* mock objects *代替 true 的依赖。

通常,您需要超越单元测试并开始集成测试(使用 Spring ApplicationContext)。能够进行集成测试而无需部署应用程序或连接到其他基础结构,这很有用。

Spring 框架包括用于此类集成测试的专用测试模块。您可以直接向org.springframework:spring-test声明依赖项,也可以使用spring-boot-starter-test“启动器”将其引入。

如果以前没有使用过spring-test模块,则应先阅读 Spring Framework 参考文档的relevant section

45.3 测试 Spring Boot 应用程序

Spring Boot 应用程序是 Spring ApplicationContext,因此除了用普通的 Spring 上下文进行测试之外,无需执行任何其他特殊操作即可对其进行测试。

Note

仅当您使用SpringApplication创建它时,Spring Boot 的外部属性,日志记录和其他功能才默认安装在上下文中。

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

Tip

如果您使用的是 JUnit 4,请不要忘记也将@RunWith(SpringRunner.class)添加到测试中,否则 Comments 将被忽略。如果您使用的是 JUnit 5,则无需添加等效的@ExtendWith(SpringExtension)作为@SpringBootTest,并且其他@…TestComments 已经对其进行了 Comments。

默认情况下,@SpringBootTest不会启动服务器。您可以使用@SpringBootTestwebEnvironment属性来进一步优化测试的运行方式:

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

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

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

  • NONE:使用SpringApplication加载ApplicationContext,但不提供任何网络环境(模拟或其他方式)。

Note

如果您的测试是@Transactional,则默认情况下它将在每个测试方法的末尾回滚事务。但是,由于将这种安排与RANDOM_PORTDEFINED_PORT一起使用隐式提供了 true 的 servlet 环境,因此 HTTP Client 端和服务器在单独的线程中运行,因此在单独的事务中运行。在这种情况下,服务器上启动的任何事务都不会回滚。

Note

如果您的应用程序对 Management 服务器使用其他端口,则@SpringBootTestwebEnvironment = WebEnvironment.RANDOM_PORT还将在单独的随机端口上启动 Management 服务器。

45.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 { ... }

45.3.2 检测测试配置

如果您熟悉 Spring Test Framework,则可能会习惯使用@ContextConfiguration(classes=…)来指定要加载哪个 Spring @Configuration。另外,您可能经常在测试中使用嵌套的@Configuration类。

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

搜索算法从包含测试的程序包开始工作,直到找到带有@SpringBootApplication@SpringBootConfigurationComments 的类。只要您以一种明智的方式结构化代码,通常就可以找到您的主要配置。

Note

如果您使用测试 Comments 以测试应用程序的更具体部分,则应避免在Main 方法的应用程序类别上添加特定于特定区域的配置设置。

@SpringBootApplication的基础组件扫描配置定义了用于确保切片按预期工作的排除筛选器。如果在@SpringBootApplicationComments 的类上使用显式的@ComponentScan指令,请注意这些过滤器将被禁用。如果使用切片,则应重新定义它们。

如果要自定义主要配置,则可以使用嵌套的@TestConfiguration类。与将使用嵌套的@Configuration类代替应用程序的主要配置不同的是,除了使用应用程序的主要配置之外,还使用嵌套的@TestConfiguration类。

Note

Spring 的测试框架在测试之间缓存应用程序上下文。因此,只要您的测试共享相同的配置(无论如何发现),加载上下文的潜在耗时过程就只会发生一次。

45.3.3 排除测试配置

如果您的应用程序使用组件扫描(例如,如果使用@SpringBootApplication@ComponentScan),则可能会偶然发现到处都是为特定测试创建的顶级配置类。

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

@RunWith(SpringRunner.class)
@SpringBootTest
@Import(MyTestsConfiguration.class)
public class MyTests {

	@Test
	public void exampleTest() {
		...
	}

}

Note

如果您直接使用@ComponentScan(即不是通过@SpringBootApplication),则需要向其注册TypeExcludeFilter。有关详情,请参见the Javadoc

45.3.4 在模拟环境中进行测试

默认情况下,@SpringBootTest不会启动服务器。如果您有要在此模拟环境下进行测试的 Web 终结点,则可以另外配置MockMvc,如以下示例所示:

import org.junit.Test;
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"));
	}

}

Tip

如果您只想关注 Web 层而不想开始完整的ApplicationContext,请考虑使用@WebMvcTest 代替

或者,您可以配置WebTestClient,如以下示例所示:

import org.junit.Test;
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");
	}

}

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

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

@LocalServerPort注解可用于注入实际使用的端口进入您的测试。为了方便起见,需要对启动的服务器进行 REST 调用的测试可以另外@Autowire a 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");
	}

}

此设置在 Classpath 上需要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");
	}

}

45.3.6 使用 JMX

由于测试上下文框架缓存上下文,因此默认情况下禁用 JMX 以防止相同组件在同一域上注册。如果此类测试需要访问MBeanServer,也请考虑将其标记为脏:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
public class SampleJmxTests {

	@Autowired
	private MBeanServer mBeanServer;

	@Test
	public void exampleTest() {
		// ...
	}

}

45.3.7 模拟 bean 和 Spybean

运行测试时,有时有必要在应用程序上下文中模拟某些组件。例如,您可能在开发期间无法使用某些远程服务的外观。当您要模拟在实际环境中可能难以触发的故障时,模拟功能也很有用。

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

Note

如果您的测试使用 Spring Boot 的测试 Comments 之一(例如@SpringBootTest),那么此功能将自动启用。要以其他方式使用此功能,必须显式添加侦听器,如以下示例所示:

@TestExecutionListeners(MockitoTestExecutionListener.class)

下面的示例使用模拟实现替换现有的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");
	}

}

另外,您可以使用@SpyBean将任何现有的 bean 与 Mockito spy包装在一起。有关详细信息,请参见Javadoc

Note

Spring 的测试框架在测试之间缓存应用程序上下文,并为共享相同配置的测试重用上下文,而@MockBean@SpyBean的使用会影响缓存键,这很可能会增加上下文的数量。

Tip

如果您使用@SpyBean监视具有通过名称引用参数的@Cacheable方法的 bean,则您的应用程序必须使用-parameters进行编译。这样可以确保一旦侦察到 bean,就可以将参数名称用于缓存基础结构。

45.3.8 自动配置的测试

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

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

Note

每个切片将组件扫描限制为适当的组件,并加载一组非常受限制的自动配置类。如果您需要排除其中之一,则大多数@…TestComments 都提供excludeAutoConfiguration属性。或者,您可以使用@ImportAutoConfiguration#exclude

Note

不支持在一个测试中使用多个@…TestComments 来包含多个“切片”。如果您需要多个“切片”,请选择@…TestComments 之一,并手动添加其他“切片”的@AutoConfigure…Comments。

Tip

也可以将@AutoConfigure…Comments 与标准@SpringBootTestComments 一起使用。如果您对“切片”应用程序不感兴趣,但需要一些自动配置的测试 bean,则可以使用此组合。

45.3.9 自动配置的 JSON 测试

要测试对象 JSON 序列化和反序列化是否按预期工作,可以使用@JsonTest注解。 @JsonTest自动配置可用的受支持的 JSON Map 器,该 Map 器可以是以下库之一:

  • JacksonObjectMapper,任何@JsonComponentbeans 和任何 JacksonModule s

  • Gson

  • Jsonb

Tip

@JsonTest启用的自动配置的列表可以为见附录

如果需要配置自动配置的元素,则可以使用@AutoConfigureJsonTestersComments。

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");
		// 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");
	}

}

Note

JSON 帮助程序类也可以直接在标准单元测试中使用。这样做,如果不使用@JsonTest,请在您的@Before方法中调用帮助程序的initFields方法。

45.3.10 自动配置的 Spring MVC 测试

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

Tip

@WebMvcTest启用的自动配置设置的列表可以为见附录

Tip

如果您需要注册其他组件,例如 Jackson Module,则可以在测试中使用@Import导入其他配置类。

通常,@WebMvcTest限于单个控制器,并与@MockBean结合使用以为所需的协作者提供模拟实现。

@WebMvcTest也会自动配置MockMvc。 Mock MVC 提供了一种强大的方法来快速测试 MVC 控制器,而无需启动完整的 HTTP 服务器。

Tip

您还可以通过用@AutoConfigureMockMvcComments 非@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"));
	}

}

Tip

如果您需要配置自动配置的元素(例如,当应用 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");
	}

}

Note

默认情况下,Spring Boot 将WebDriver bean 放在特殊的“作用域”中,以确保驱动程序在每次测试后退出并注入新实例。如果您不希望出现这种情况,可以将@Scope("singleton")添加到WebDriver @Bean定义中。

Warning

Spring Boot 创建的webDriver作用域将替换任何用户定义的同名作用域。如果定义自己的webDriver范围,则使用@WebMvcTest时可能会停止工作。

如果您在 Classpath 上具有 Spring Security,则@WebMvcTest还将扫描WebSecurityConfigurer bean。您可以使用 Spring Security 的测试支持,而不是完全禁用此类测试的安全性。有关如何使用 Spring Security 的MockMvc支持的更多详细信息,可以在此* 第 80 章,使用 Spring Security 进行测试 *操作方法部分中找到。

Tip

有时编写 Spring MVC 测试是不够的。 Spring Boot 可以帮助您运行使用实际服务器进行完整的端到端测试

45.3.11 自动配置的 Spring WebFlux 测试

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

Tip

@WebFluxTest启用的自动配置的列表可以为见附录

Tip

如果您需要注册其他组件,例如 Jackson Module,则可以在测试中使用@Import导入其他配置类。

@WebFluxTest通常仅限于单个控制器,并与@MockBean注解结合使用以为所需的协作者提供模拟实现。

@WebFluxTest还自动配置WebTestClient,它提供了一种强大的方法来快速测试 WebFlux 控制器而无需启动完整的 HTTP 服务器。

Tip

您还可以通过用@AutoConfigureWebTestClientComments 非@WebFluxTest(例如@SpringBootTest)来自动配置WebTestClient。以下示例显示了同时使用@WebFluxTestWebTestClient的类:

import org.junit.Test;
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");
	}

}

Tip

WebFlux 应用程序仅支持此设置,因为在模拟的 Web 应用程序中使用WebTestClient目前仅适用于 WebFlux。

Note

@WebFluxTest无法检测通过功能 Web 框架注册的路由。要在上下文中测试RouterFunction bean,请考虑自己通过@Import或使用@SpringBootTest导入RouterFunction

Tip

有时编写 Spring WebFlux 测试是不够的。 Spring Boot 可以帮助您运行使用实际服务器进行完整的端到端测试

45.3.12 自动配置的数据 JPA 测试

您可以使用@DataJpaTest注解来测试 JPA 应用程序。默认情况下,它配置一个内存嵌入式数据库,扫描@Entity类,并配置 Spring Data JPA 存储库。常规@Component bean 未加载到ApplicationContext中。

Tip

@DataJpaTest启用的自动配置设置的列表可以为见附录

默认情况下,数据 JPA 测试是事务性的,并在每次测试结束时回滚。有关更多详细信息,请参见《 Spring Framework 参考文档》中的relevant section。如果这不是您想要的,则可以按以下方式禁用测试或整个类的事务 Management:

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 {

}

数据 JPA 测试还可以注入TestEntityManager bean,它提供了专门为测试设计的标准 JPA EntityManager的替代方案。如果要在@DataJpaTest实例之外使用TestEntityManager,则也可以使用@AutoConfigureTestEntityManagerComments。如果需要,也可以提供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 {

	// ...

}

45.3.13 自动配置的 JDBC 测试

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

Tip

@JdbcTest启用的自动配置的列表可以为见附录

缺省情况下,JDBC 测试是事务性的,并在每次测试结束时回滚。有关更多详细信息,请参见《 Spring Framework 参考文档》中的relevant section。如果这不是您想要的,则可以为测试或整个类禁用事务 Management,如下所示:

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 {

}

如果您希望测试针对真实数据库运行,则可以使用 Comments,方式与DataJpaTest相同。 (请参阅“ 第 45.3.12 节,“自动配置的数据 JPA 测试””。)

45.3.14 自动配置的数据 JDBC 测试

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

Tip

@DataJdbcTest启用的自动配置的列表可以为见附录

默认情况下,Data JDBC 测试是事务性的,并在每个测试结束时回滚。有关更多详细信息,请参见《 Spring Framework 参考文档》中的relevant section。如果这不是您想要的,则可以禁用测试或整个测试类的事务 Management,即在 JDBC 示例中显示

如果您希望测试针对真实数据库运行,则可以使用 Comments,方式与DataJpaTest相同。 (请参阅“ 第 45.3.12 节,“自动配置的数据 JPA 测试””。)

45.3.15 自动配置的 jOOQ 测试

您可以以与@JdbcTest类似的方式使用@JooqTest,但可以用于与 jOOQ 相关的测试。由于 jOOQ 严重依赖与数据库模式相对应的基于 Java 的模式,因此使用现有的DataSource。如果要将其替换为内存数据库,则可以使用@AutoConfigureTestDatabase覆盖这些设置。 (有关将 jOOQ 与 Spring Boot 结合使用的更多信息,请参阅本章前面的“ 第 30.6 节“使用 jOOQ””。)常规@Component bean 没有加载到ApplicationContext中。

Tip

@JooqTest启用的自动配置的列表可以为见附录

@JooqTest配置DSLContext。常规@Component bean 未加载到ApplicationContext中。以下示例显示了正在使用的@JooqTestComments:

import org.jooq.DSLContext;
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 测试是事务性的,默认情况下会在每个测试结束时回滚。如果这不是您想要的,则可以禁用测试或整个测试类的事务 Management,例如在 JDBC 示例中显示

45.3.16 自动配置的 Data MongoDB 测试

您可以使用@DataMongoTest测试 MongoDB 应用程序。默认情况下,它配置内存嵌入式 MongoDB(如果可用),配置MongoTemplate,扫描@Document类,并配置 Spring Data MongoDB 存储库。常规@Component bean 没有加载到ApplicationContext中。 (有关将 MongoDB 与 Spring Boot 结合使用的更多信息,请参阅本章前面的“ 第 31.2 节“ MongoDB””。)

Tip

@DataMongoTest启用的自动配置设置的列表可以为见附录

此类显示正在使用的@DataMongoTest注解:

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 {

}

45.3.17 自动配置的数据 Neo4j 测试

您可以使用@DataNeo4jTest测试 Neo4j 应用程序。默认情况下,它使用内存中嵌入式 Neo4j(如果有嵌入式驱动程序可用),扫描@NodeEntity类,并配置 Spring Data Neo4j 存储库。常规@Component bean 没有加载到ApplicationContext中。 (有关将 Neo4J 与 Spring Boot 结合使用的更多信息,请参阅本章前面的“ 第 31.3 节“ Neo4j””。)

Tip

@DataNeo4jTest启用的自动配置设置的列表可以为见附录

以下示例显示了在 Spring Boot 中使用 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 Framework 参考文档》中的relevant section。如果这不是您想要的,则可以为测试或整个类禁用事务 Management,如下所示:

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 {

}

45.3.18 自动配置的数据 Redis 测试

您可以使用@DataRedisTest测试 Redis 应用程序。默认情况下,它将扫描@RedisHash类并配置 Spring Data Redis 存储库。常规@Component bean 没有加载到ApplicationContext中。 (有关在 Spring Boot 中使用 Redis 的更多信息,请参阅本章前面的“ 第 31.1 节“ Redis””。)

Tip

@DataRedisTest启用的自动配置设置的列表可以为见附录

以下示例显示了正在使用的@DataRedisTest注解:

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;

	//
}

45.3.19 自动配置的数据 LDAP 测试

您可以使用@DataLdapTest测试 LDAP 应用程序。默认情况下,它配置内存嵌入式 LDAP(如果可用),配置LdapTemplate,扫描@Entry类,并配置 Spring Data LDAP 存储库。常规@Component bean 没有加载到ApplicationContext中。 (有关将 LDAP 与 Spring Boot 结合使用的更多信息,请参阅本章前面的“ 第 31.9 节“ LDAP””。)

Tip

@DataLdapTest启用的自动配置设置的列表可以为见附录

以下示例显示了正在使用的@DataLdapTest注解:

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 {

}

45.3.20 自动配置的 REST Client 端

您可以使用@RestClientTest注解来测试 REST Client 端。默认情况下,它会自动配置 Jackson,GSON 和 Jsonb 支持,配置RestTemplateBuilder,并添加对MockRestServiceServer的支持。常规@Component bean 没有加载到ApplicationContext中。

Tip

@RestClientTest启用的自动配置设置的列表可以为见附录

应该使用@RestClientTestvaluecomponents属性指定要测试的特定 bean,如以下示例所示:

@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");
	}

}

45.3.21 自动配置的 Spring REST 文档测试

您可以在 Mock MVC,REST 保证或 WebTestClient 的测试中使用@AutoConfigureRestDocs注解来使用Spring REST 文件。它消除了 Spring REST Docs 中对 JUnit 规则的需求。

@AutoConfigureRestDocs可用于覆盖默认输出目录(如果使用 Maven,则使用target/generated-snippets;如果使用 Gradle,则使用build/generated-snippets)。它也可以用于配置出现在任何记录的 URI 中的主机,方案和端口。

使用 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 保证的自动配置的 Spring REST 文档测试

@AutoConfigureRestDocs使预配置为使用 Spring REST 文档的RequestSpecification bean 可用于您的测试。您可以使用@Autowired注入它,并像在使用 REST Assured 和 Spring REST Docs 时一样,在测试中使用它,如以下示例所示:

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());
	}

}

45.3.22 其他自动配置和切片

每个切片提供一个或多个@AutoConfigure…注解,即定义应包含在切片中的自动配置。可以通过创建自定义@AutoConfigure…Comments 或仅通过向测试中添加@ImportAutoConfiguration来添加其他自动配置,如以下示例所示:

@RunWith(SpringRunner.class)
@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
public class ExampleJdbcTests {

}

Note

确保不要使用常规的@ImportComments 来导入自动配置,因为它们是由 Spring Boot 以特定方式处理的。

45.3.23 用户配置和切片

如果您以明智的方式结构化代码,则您的@SpringBootApplication类为默认使用作为测试的配置。

因此,重要的是不要用特定于其功能特定区域的配置设置来乱扔应用程序的主类。

假设您正在使用 Spring Batch,并且依赖于它的自动配置。您可以按以下方式定义@SpringBootApplication

@SpringBootApplication
@EnableBatchProcessing
public class SampleApplication { ... }

因为此类是测试的源配置,所以任何切片测试实际上都尝试启动 Spring Batch,这绝对不是您想要执行的操作。建议的方法是将特定于区域的配置移到与您的应用程序相同级别的单独的@Configuration类,如以下示例所示:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration { ... }

Note

根据您应用程序的复杂性,您可以为自己的自定义设置一个@Configuration类,或者每个域区域一个类。后一种方法可让您在必要的测试中使用@Import注解启用它。

混乱的另一个来源是 Classpath 扫描。假设在以合理的方式组织代码的同时,您需要扫描其他程序包。您的应用程序可能类似于以下代码:

@SpringBootApplication
@ComponentScan({ "com.example.app", "org.acme.another" })
public class SampleApplication { ... }

这样做有效地覆盖了默认的组件扫描指令,并且具有扫描这两个软件包的副作用,而与您选择的切片无关。例如,@DataJpaTest似乎突然扫描了应用程序的组件和用户配置。同样,将自定义指令移至单独的类是解决此问题的好方法。

Tip

如果这不是您的选择,则可以在测试层次结构中的某个位置创建@SpringBootConfiguration,以便代替它使用。另外,您可以为测试指定一个源,从而禁用查找默认源的行为。

45.3.24 使用 Spock 测试 Spring Boot 应用程序

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

45.4 测试 Util

一些测试 Util 类通常在测试您的应用程序时有用,它们被打包为spring-boot的一部分。

45.4.1 ConfigFileApplicationContextInitializer

ConfigFileApplicationContextInitializerApplicationContextInitializer,您可以将其应用于测试以加载 Spring Boot application.properties文件。如不需要以下示例所示,可以在不需要@SpringBootTest提供的全部功能时使用它:

@ContextConfiguration(classes = Config.class,
	initializers = ConfigFileApplicationContextInitializer.class)

Note

单独使用ConfigFileApplicationContextInitializer不支持@Value("${…}")注入。它唯一的工作就是确保将application.properties文件加载到 Spring 的Environment中。为了获得@Value支持,您需要另外配置PropertySourcesPlaceholderConfigurer或使用@SpringBootTest,后者会为您自动配置一个。

45.4.2 TestPropertyValues

TestPropertyValues可让您快速将属性添加到ConfigurableEnvironmentConfigurableApplicationContext。您可以使用key=value字符串来调用它,如下所示:

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

45.4.3 OutputCapture

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

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"));
	}

}

45.4.4 TestRestTemplate

Tip

Spring Framework 5.0 提供了一个新的WebTestClient,它适用于WebFlux 集成测试WebFlux 和 MVC 端到端测试。与TestRestTemplate不同,它为声明提供了流畅的 API。

TestRestTemplate是 Spring RestTemplate的便捷替代方法,在集成测试中非常有用。您可以使用普通模板或发送基本 HTTP 身份验证(带有用户名和密码)的模板。在这两种情况下,模板都不会通过在服务器端错误上引发异常来以易于测试的方式运行。建议(但不是强制性的)使用 Apache HTTP Client(版本 4.3.2 或更高版本)。如果您在 Classpath 中具有该名称,则TestRestTemplate会通过适当配置 Client 端进行响应。如果确实使用 Apache 的 HTTP Client 端,则会启用一些其他易于测试的功能:

  • 不遵循重定向(因此您可以声明响应位置)。

  • Cookies 被忽略(因此模板是 Stateless 的)。

TestRestTemplate可以在集成测试中直接实例化,如以下示例所示:

public class MyTest {

	private TestRestTemplate template = new TestRestTemplate();

	@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");
	}

}

另外,如果您将@SpringBootTestComments 与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));
		}

	}

}