How to mock RestTemplate with MockRestServiceServer?

@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
    @Autowired
    RestTemplate restTemplate = new RestTemplate();
    @Autowired
    Service service = new Service();
    MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);

    @Test
    public void test() throws Exception {
      mockServer.expect(requestTo(Mockito.anyString()))
                .andRespond(withSuccess("{"enabled":true}", MediaType.APPLICATION_JSON));
        boolean res = service.isEnabled("xxx");
        mockServer.verify();
        Assert.assertEquals(true, res);
    }
}

I have MockRestServiceServer to mock restTemplete in a service. But it always fail. it shows the error as java.lang.AssertionError: Further request(s) expected 0 out of 1 were executed. Any one could let me know where I did not do it right.

The service itself will looks as this:

public class Service{
    public boolean isEnabled(String xxx) {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
        if(...)return true;
        return false;
    }
}

Answer

First of all, your Service class creates a new instance of RestTemplate on every request. I cannot stress enough how bad practice it is. Create a bean of type RestTemplate and inject it into your Service bean (it is most likely already created – depending on the Spring MVC version you are using).

Once you have it, then both RestTemplates: one in your Service bean and one injected into FeatureFlipperManagerTest will be the same and testing with MockRestServiceServer will be possible.

EDIT – to be more explicit:

Modify your Service class to:

@Component
public class Service {

    private RestTemplate restTemplate;  

    @Autowired 
    public Service(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public boolean isEnabled(String xxx) {
        ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
        if(...)return true;
        return false;
    }
}

and your test class to:

@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
    @Autowired
    RestTemplate restTemplate;

    @Autowired
    Service service;

    MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);

    @Test
    public void test() throws Exception {
      mockServer.expect(requestTo(Mockito.anyString()))
                .andRespond(withSuccess("{"enabled":true}", MediaType.APPLICATION_JSON));
        boolean res = service.isEnabled("xxx");
        mockServer.verify();
        Assert.assertEquals(true, res);
    }
}

If this fails with exception saying that there is no RestTemplate bean present then please paste info about version of Spring (Spring Boot?) you are using.

Leave a Reply

Your email address will not be published. Required fields are marked *