Testing Spring Boots caching behavior in a RestClientTest

Viewed 152

I have the following scenario:

A Service calls some rest endpoint to query a resource. The result of this query should be cached for one day and then requeried.

To verify this behavior I wrote a test that calls the service method 2 times and expects that the rest service was actually only queried one time.

Here would be the class that calls the endpoint:

@EnableCaching
@Service
public class CachedResourceClient {    
    private final RestTemplate restTemplate;

    public CachedResourceClient(@Value("${api.host}") String apiHost, RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder
            .rootUri(apiHost)
            .build();
    }

    @Cacheable("resource")
    public Optional<Resource> fetchResource() {
        try {
            return Optional.of(restTemplate.getForObject("/resource", Resource.class));
        } catch (HttpClientErrorException | HttpServerErrorException | UnknownHttpStatusCodeException e) {
            // logging
            return Optional.empty();
        }
    }
}

and then we have this test here:

@RestClientTest(CachedResourceClient.class)
public class CachedResourceClientTests {
    @Autowired
    private MockRestServiceServer server;
    
    @Autowired
    private CachedResourceClient cachedResourceClient;

    @Test
    public void fetchResource() throws JsonProcessingException {
        server.expect(requestTo("/resource"))
              .andRespond(withSuccess("{ resource: 'some' }", MediaType.APPLICATION_JSON));
        cachedResourceClient.fetchResource();
        cachedResourceClient.fetchResource();
        server.verify();
    }
}

As you can see, we're calling the fetchResource method two times. But the server.verify call fails, because there are also two requests sent to the mock server.

I think the RestClientTest does something behind the scene with my CachedResourceClient that conflicts with the way Caching is setup.

Because if I remove the RestClientTest-Annotation and manually mock the RestTemplateBuilder and the RestTemplate the tests work as expected. But having a server mock is a bit more comfortable than manually mocking the used classes.

Is there something wrong with the setup?

0 Answers
Related