It should be possible to have together RestTemplate and RestClient in application and test them independently.
Unfortunately, currently if RestTemplate is used, RestClient cannot be tested:
org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerAutoConfiguration.DeferredRequestExpectationManager#getDelegate
if (!restTemplateExpectationManagers.isEmpty()) {
Assert.state(restTemplateExpectationManagers.size() == 1,
"Unable to use auto-configured MockRestServiceServer since "
+ "MockServerRestTemplateCustomizer has been bound to more than one RestTemplate");
return restTemplateExpectationManagers.values().iterator().next();
}
Assert.state(restClientExpectationManagers.size() == 1,
"Unable to use auto-configured MockRestServiceServer since "
+ "MockServerRestClientCustomizer has been bound to more than one RestClient");
return restClientExpectationManagers.values().iterator().next();
**Comment From: philwebb**
I'm not sure I understand your setup. Could you please provide a minimal sample project (either a GitHub project or zip file) that shows what you are trying to do.
**Comment From: michaldo**
Voila: https://github.com/michaldo/rest-client-and-template-together
**Comment From: mhalbritter**
The problem is in `org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerAutoConfiguration.DeferredRequestExpectationManager#getDelegate`:
When a `RestTemplate` is in the context, `restTemplateExpectationManagers` contains 1 entry, which is then always used. The expectation manager, which may be in `restClientExpectationManagers` is then ignored.
I suspect that the RestClient case then uses the wrong expectation manager when the mocked response is returned.
That's the error I'm getting:
java.lang.AssertionError: No further requests expected: HTTP GET / 0 request(s) executed.
at org.springframework.test.web.client.AbstractRequestExpectationManager.createUnexpectedRequestError(AbstractRequestExpectationManager.java:193)
at org.springframework.test.web.client.SimpleRequestExpectationManager.matchRequest(SimpleRequestExpectationManager.java:59)
at org.springframework.test.web.client.AbstractRequestExpectationManager.validateRequest(AbstractRequestExpectationManager.java:91)
at org.springframework.test.web.client.MockRestServiceServer$MockClientHttpRequestFactory$1.executeInternal(MockRestServiceServer.java:324)
at org.springframework.mock.http.client.MockClientHttpRequest.execute(MockClientHttpRequest.java:126)
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:453)
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.retrieve(DefaultRestClient.java:424)
at com.example.restclientjson.RestClientAndTemplateTogetherTest.test(RestClientAndTemplateTogetherTest.java:42)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
**Comment From: scottfrederick**
If you have two `RestTemplate` beans or two `RestClient` beans in your application, you can't use an auto-wired `MockRestServiceServer` in your test. If you do, you will get an exception with a message like `Unable to use auto-configured MockRestServiceServer since MockServerRestTemplateCustomizer has been bound to more than one RestTemplate` when you try to set an expectation. This is mentioned in the [JavaDoc](https://github.com/spring-projects/spring-boot/blob/3.2.x/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/client/AutoConfigureMockRestServiceServer.java#L34-L44) for `AutoConfigureMockRestServiceServer.java` but the language is not completely clear:
> If multiple [RestTemplates](https://docs.spring.io/spring-framework/docs/6.1.2/javadoc-api/org/springframework/web/client/RestTemplate.html) or [RestClients](https://docs.spring.io/spring-framework/docs/6.1.2/javadoc-api/org/springframework/web/client/RestClient.html) are in use, inject a [MockServerRestTemplateCustomizer](https://docs.spring.io/spring-boot/docs/3.2.x/api/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizer.html) and use [getServer(RestTemplate)](https://docs.spring.io/spring-boot/docs/3.2.x/api/org/springframework/boot/test/web/client/MockServerRestTemplateCustomizer.html#getServer(org.springframework.web.client.RestTemplate)), or inject a [MockServerRestClientCustomizer](https://docs.spring.io/spring-boot/docs/3.2.x/api/org/springframework/boot/test/web/client/MockServerRestClientCustomizer.html) and use [ getServer(RestClient.Builder)](https://docs.spring.io/spring-boot/docs/3.2.x/api/org/springframework/boot/test/web/client/MockServerRestClientCustomizer.html#getServer(org.springframework.web.client.RestClient.Builder)), or bind a [MockRestServiceServer](https://docs.spring.io/spring-framework/docs/6.1.2/javadoc-api/org/springframework/test/web/client/MockRestServiceServer.html) directly.
The same is true when you have one `RestTemplate` and one `RestClient`, but this condition is not currently detected in the code like it should be so that an exception with a descriptive message can be thrown. We'll fix that.
Applying the suggestion from the JavaDoc to the provided sample would look like this:
```java
@Test
void test(@Autowired RestClient restClient, @Autowired MockServerRestClientCustomizer customizer) {
// given
customizer.getServer().expect(requestTo("/")).andRespond(withSuccess());
// when then
restClient.get()
.uri("/")
.retrieve();
}