How to mock RestTemplet with MockRestServiceServer?

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

@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;     } } 

回答1:

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.



回答2:

I think you mean you want to use RestTemplate which is provided by spring, so you should createServer after the spring autowired the RestTemplate. I think you can do it like this:

@RunWith(MockitoJUnitRunner.class) public class FeatureFlipperManagerTest {     @Autowired     RestTemplate restTemplate;      Service service;     MockRestServiceServer mockServer;      @Before     public void init() {         service = new Service();          service.setRestTemplate(restTemplate);         // If you have autowired restTemplate in Service, you can just autowired the service         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);     } } 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!