1. Introduction
1.介绍
This article is a quick introduction to the @RestClientTest annotation.
这篇文章是对@RestClientTest注解的快速介绍。
The new annotation helps simplify and speed up the testing of REST clients in your Spring applications.
这个新注解有助于简化和加快Spring应用程序中REST客户端的测试。
2. REST Client Support in Spring Boot Pre-1.4
2.Spring Boot Pre-1.4中的REST客户端支持
Spring Boot is a handy framework that provides many auto-configured Spring beans with typical settings that allow you to concentrate less on configuration of a Spring application and more on your code and business logic.
Spring Boot是一个方便的框架,它提供了许多具有典型设置的自动配置的Spring Bean,使你可以减少对Spring应用的配置,而更多地关注你的代码和业务逻辑。
But in version 1.3 we don’t get a lot of help when we want to create or test REST services clients. Its support for REST clients is not very deep.
但是在1.3版本中,当我们想创建或测试REST服务客户端时,我们没有得到很多帮助。它对REST客户端的支持不是很深入。
To create a client for a REST API – a RestTemplate instance is typically used. Usually it has to be configured before usage and its configuration may vary, so Spring Boot does not provide any universally configured RestTemplate bean.
要为REST API创建一个客户端,通常要使用RestTemplate实例。通常,在使用前必须对其进行配置,其配置可能会有所不同,因此Spring Boot没有提供任何普遍配置的RestTemplate Bean。
Same goes for testing REST clients. Before Spring Boot 1.4.0, the procedure of testing a Spring REST client was not very different than in any other Spring-based application. You would create a MockRestServiceServer instance, bind it to RestTemplate instance under test and provide it with mock responses to requests, like this:
测试REST客户端也是如此。在Spring Boot 1.4.0之前,测试Spring REST客户端的程序与其他基于Spring的应用程序没有太大区别。你可以创建一个MockRestServiceServer实例,将其与被测的RestTemplate实例绑定,并向其提供模拟的请求响应,就像这样。
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer =
MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/greeting"))
.andRespond(withSuccess());
// Test code that uses the above RestTemplate ...
mockServer.verify();
You would also have to initialize the Spring container and make sure that only the needed components are loaded into the context, to speed up the context load time (and consequently, the test execution time).
你还必须初始化Spring容器,确保只有需要的组件被加载到上下文中,以加快上下文的加载时间(以及随之而来的测试执行时间)。
3. New REST Client Features in Spring Boot 1.4+
3.Spring Boot 1.4+中新的REST客户端功能
In Spring Boot 1.4, the team has made a solid effort to simplify and speed up the creation and testing of REST clients.
在Spring Boot 1.4中,团队为简化和加快REST客户端的创建和测试做出了坚实的努力。
So, let’s check out the new features.
那么,让我们来看看这些新功能。
3.1. Adding Spring Boot to Your Project
3.1.将Spring Boot添加到您的项目中
First, you’ll need to make sure your project is using Spring Boot 1.4.x or higher:
首先,你需要确保你的项目使用的是Spring Boot 1.4.x或更高版本。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Newest release versions can be found here.
最新的发布版本可以在这里找到。
3.2. RestTemplateBuilder
3.2.RestTemplateBuilder
Spring Boot brings both the auto-configured RestTemplateBuilder to simplify creating RestTemplates, and the matching @RestClientTest annotation to test the clients built with RestTemplateBuilder. Here’s how you can create a simple REST client with RestTemplateBuilder auto-injected for you:
Spring Boot既带来了自动配置的RestTemplateBuilder,以简化创建RestTemplates,也带来了匹配的@RestClientTest注释,以测试用RestTemplateBuilder构建的客户端。下面是你如何创建一个简单的REST客户端,并为你自动注入RestTemplateBuilder。
@Service
public class DetailsServiceClient {
private final RestTemplate restTemplate;
public DetailsServiceClient(RestTemplateBuilder restTemplateBuilder) {
restTemplate = restTemplateBuilder.build();
}
public Details getUserDetails(String name) {
return restTemplate.getForObject("/{name}/details",
Details.class, name);
}
}
Notice that we did not explicitly wire the RestTemplateBuilder instance to a constructor. This is possible thanks to a new Spring feature called implicit constructor injection, which is discussed in this article.
请注意,我们没有明确地将RestTemplateBuilder实例连接到一个构造函数。这要归功于Spring的一个新特性,即隐式构造函数注入,该特性在这篇文章中讨论。
RestTemplateBuilder provides convenience methods for registering message converters, error handlers, URI template handlers, basic authorization and also use any additional customizers that you need.
RestTemplateBuilder为注册消息转换器、错误处理程序、URI模板处理程序、基本授权以及使用任何你需要的额外定制器提供了便利方法。
3.3. @RestClientTest
3.3.@RestClientTest
For testing such a REST client built with RestTemplateBuilder, you may use a SpringRunner-executed test class annotated with @RestClientTest. This annotation disables full auto-configuration and only applies configuration relevant to REST client tests, i.e. Jackson or GSON auto-configuration and @JsonComponent beans, but not regular @Component beans.
对于测试这样一个用RestTemplateBuilder构建的REST客户端,你可以使用一个SpringRunner执行的测试类,其注释为@RestClientTest。这个注解禁用了完全的自动配置,只应用与REST客户端测试相关的配置,即Jackson或GSON自动配置和@JsonComponentBean,而不是普通的@ComponentBean。
@RestClientTest ensures that Jackson and GSON support is auto-configured, and also adds pre-configured RestTemplateBuilder and MockRestServiceServer instances to the context. The bean under test is specified with value or components attribute of the @RestClientTest annotation:
@RestClientTest确保Jackson和GSON支持被自动配置,并且还将预配置的RestTemplateBuilder和MockRestServiceServer实例添加到上下文。被测Bean是用value或components属性的@RestClientTest注解指定的。
@RunWith(SpringRunner.class)
@RestClientTest(DetailsServiceClient.class)
public class DetailsServiceClientTest {
@Autowired
private DetailsServiceClient client;
@Autowired
private MockRestServiceServer server;
@Autowired
private ObjectMapper objectMapper;
@Before
public void setUp() throws Exception {
String detailsString =
objectMapper.writeValueAsString(new Details("John Smith", "john"));
this.server.expect(requestTo("/john/details"))
.andRespond(withSuccess(detailsString, MediaType.APPLICATION_JSON));
}
@Test
public void whenCallingGetUserDetails_thenClientMakesCorrectCall()
throws Exception {
Details details = this.client.getUserDetails("john");
assertThat(details.getLogin()).isEqualTo("john");
assertThat(details.getName()).isEqualTo("John Smith");
}
}
Firstly, we need to ensure that this test is run with SpringRunner by adding the @RunWith(SpringRunner.class) annotation.
首先,我们需要通过添加@RunWith(SpringRunner.class)注解来确保该测试在SpringRunner下运行。
So, what’s new?
那么,什么是新的?。
First – the @RestClientTest annotation allows us to specify the exact service under test – in our case it is the DetailsServiceClient class. This service will be loaded into the test context, while everything else is filtered out.
首先—@RestClientTest注解允许我们指定被测试的确切服务–在我们的例子中是DetailsServiceClient类。这个服务将被加载到测试上下文中,而其他一切都被过滤掉了。
This allows us to autowire the DetailsServiceClient instance inside our test and leave everything else outside, which speeds up the loading of the context.
这允许我们在测试中自动连接DetailsServiceClient实例,而将其他一切留在外面,这就加快了上下文的加载。
Second – as the MockRestServiceServer instance is also configured for a @RestClientTest-annotated test (and bound to the DetailsServiceClient instance for us), we can simply inject it and use.
第二 – 由于MockRestServiceServer实例也被配置为@RestClientTest注释的测试(并为我们绑定到DetailsServiceClient实例),我们可以简单地注入它并使用。
Finally – JSON support for @RestClientTest allows us to inject the Jackson’s ObjectMapper instance to prepare the MockRestServiceServer’s mock answer value.
最后–对@RestClientTest的JSON支持使我们能够注入Jackson的ObjectMapper实例来准备MockRestServiceServer的模拟答案值。
All that is left to do is to execute the call to our service and verify the results.
剩下的就是执行对我们服务的调用并验证结果。
4. Conclusion
4.结论
In this article we’ve discussed the new @RestClientTest annotation that allows easy and quick testing of REST clients built with Spring.
在这篇文章中,我们讨论了新的@RestClientTest注解,它允许对用Spring构建的REST客户端进行简单而快速的测试。
The source code for the article is available on GitHub.
文章的源代码可在GitHub上获得,。