I want to test outgoing HTTP calls from my service using MockRestServiceServer. I got it working using following code:
@SpringBootTest
class CommentFetcherTest {
@Autowired
RestTemplate restTemplate;
@Autowired
CommentFetcher commentFetcher;
@Test
public void shouldCallExternalService(){
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
mockServer.expect(ExpectedCount.once(), requestTo("/test/endpoint")).andExpect(method(HttpMethod.GET));
//when
commentFetcher.fetchData();
mockServer.verify();
}
}
However the problem I run into is that RestTemplate is a bean shared between all tests from suite what makes impossible to further run integration tests which should be calling external services. This results in :
java.lang.AssertionError: No further requests expected
How is it possible to use MockRestServiceServer only for subset of tests?
I can't get rid of Dependency Injection through @Autowired and construct my service in tests such as
RestTemplate restTemplate = new RestTemplate();
CommentFetcher commentFetcher = new CommentFetcher(restTemplate);
As this would not read properties from application.properties necessary to proper functioning of my service.
Spring Boot provides a convenient way to test your client classes that make use of Spring's
RestTemplateusing@RestClientTest.With this annotation, you get a Spring Test Context that only contains relevant beans and not your whole application context (which is what you currently get with
@SpringBootTest).The
MockRestServiceServeris also part of this context and theRestTemplateis configured to target it.A basic test setup can look like the following:
What's left is to stub the HTTP method call and then invoke the method on your class under test (
commentFetcher.fetchData();in your case).Refer to this article if you want to understand more about how
@RestClientTestcan be used to test yourRestTemplateusage.