0

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.

xwhyz
  • 1,444
  • 4
  • 21
  • 45
  • Not sure if I fully understand the big picture here, but will it be possible for you to autowire `TestRestTemplate` in your integration test classes? BR – Roar S. Jan 04 '21 at 13:36

1 Answers1

1

Spring Boot provides a convenient way to test your client classes that make use of Spring's RestTemplate using @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 MockRestServiceServer is also part of this context and the RestTemplate is configured to target it.

A basic test setup can look like the following:

@RestClientTest(CommentFetcher.class)
class UserClientTest {
 
  @Autowired
  private CommentFetcher userClient;
 
  @Autowired
  private MockRestServiceServer mockRestServiceServer;
 
  // ...
 
 
}

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 @RestClientTest can be used to test your RestTemplate usage.

rieckpil
  • 10,470
  • 3
  • 32
  • 56