Josh C Josh C - 3 months ago 141
reST (reStructuredText) Question

Spring-Boot RestClientTest not correctly auto-configuring MockRestServiceServer due to unbound RestTemplate

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

Problem:

According to the documentation the @RestClientTest should correctly configure a MockRestServiceServer to use when testing a REST client. However when running a test I am getting an IllegalStateException saying the MockServerRestTemplateCustomizer has not been bound to a RestTemplate.

Its worth noting that I'm using Gson for deserialization and not Jackson, hence the exclude.

Does anyone know how to correctly use this new annotation? I haven't found any examples that require more configuration then when I have already.

Configuration:

@SpringBootConfiguration
@ComponentScan
@EnableAutoConfiguration(exclude = {JacksonAutoConfiguration.class})
public class ClientConfiguration {

...

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


Client:

@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 the Exception:

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

Answer

You have RestTemplateBuilder at two places. At ClientConfiguration class and at ComponentsClientImpl class. Remove below code from ClientConfiguration class and run your test.

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