Spring -Boot RestClientTest does not auto-configure MockRestServiceServer due to unbound RestTemplate

EDIT: This question specifically refers to the @RestClientTest annotation introduced in spring-boot 1.4.0, which is intended to replace the factory method.

Problem:

According to the documentation, @RestClientTest should properly configure the MockRestServiceServer to use when testing the REST client. However, when I run the test, I get an IllegalStateException exception that indicates that the MockServerRestTemplateCustomizer is not bound to the RestTemplate.

It is worth noting that I use Gson for deserialization, not for Jackson, so an exception.

Does anyone know how to properly use this new annotation? I did not find examples requiring more configuration, and then when I already have it.

Configuration:

@SpringBootConfiguration @ComponentScan @EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class}) public class ClientConfiguration { ... @Bean public RestTemplateBuilder restTemplateBuilder() { return new RestTemplateBuilder() .rootUri(rootUri) .basicAuthorization(username, password); } } 

Customer:

 @Service public class ComponentsClientImpl implements ComponentsClient { private RestTemplate restTemplate; @Autowired public ComponentsClientImpl(RestTemplateBuilder builder) { this.restTemplate = builder.build(); } public ResponseDTO getComponentDetails(RequestDTO requestDTO) { HttpEntity<RequestDTO> entity = new HttpEntity<>(requestDTO); ResponseEntity<ResponseDTO> response = restTemplate.postForEntity("/api", entity, ResponseDTO.class); return response.getBody(); } } 

Test

 @RunWith(SpringRunner.class) @RestClientTest(ComponentsClientImpl.class) public class ComponentsClientTest { @Autowired private ComponentsClient client; @Autowired private MockRestServiceServer server; @Test public void getComponentDetailsWhenResultIsSuccessShouldReturnComponentDetails() throws Exception { server.expect(requestTo("/api")) .andRespond(withSuccess(getResponseJson(), APPLICATION_JSON)); ResponseDTO response = client.getComponentDetails(requestDto); ResponseDTO expected = responseFromJson(getResponseJson()); assertThat(response, is(expectedResponse)); } } 

And an exception:

 java.lang.IllegalStateException: Unable to use auto-configured MockRestServiceServer since MockServerRestTemplateCustomizer has not been bound to a RestTemplate 

Answer:

As per the answer below, there is no need to declare a RestTemplateBuilder bean in context, as it is already provided by the automatic spring-boot configuration.

If the project is a spring-boot application (it has the @SpringBootApplication annotation), this will work as intended. However, in the aforementioned case, the project was a client library and, therefore, did not have a main application.

To ensure that the RestTemplateBuilder has been correctly entered into the main application context (the bean has been removed), a CUSTOM filter (the one used by @SpringBootApplication) is required to check the components

 @ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class) }) 
+5
source share
2 answers

You have a RestTemplateBuilder in two places. In the ClientConfiguration class and in the ComponentsClientImpl class. Spring boot 1.4.0 automatically configures a RestTemplateBuilder, which can be used to create RestTemplate instances if necessary. Remove the code below from the ClientConfiguration class and run the test.

  @Bean public RestTemplateBuilder restTemplateBuilder() { return new RestTemplateBuilder() .rootUri(rootUri) .basicAuthorization(username, password); } 
+3
source

A MockRestServiceServer instance must be created from a static factory using a RestTemplate . See this article for a detailed description of the testing process.

In your example, you can do:

 @RunWith(SpringRunner.class) @RestClientTest(ComponentsClientImpl.class) public class ComponentsClientTest { @Autowired private ComponentsClient client; @Autowired private RestTemplate template; private MockRestServiceServer server; @Before public void setUp() { server= MockRestServiceServer.createServer(restTemplate); } /*Do your test*/ } 
+2
source

All Articles