如何使用 MockRestServiceServer 模拟 RestTemplate?

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

我有 MockRestServiceServer 在服务中模拟 restTemplete.但它总是失败.它将错误显示为 java.lang.AssertionError: Additional request(s) expected1 个中有 0 个被执行.任何人都可以让我知道我哪里做得不对.

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.

服务本身将如下所示:

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

推荐答案

首先,您的 Service 类在每次请求时都会创建一个新的 RestTemplate 实例.我不能强调这是多么糟糕的做法.创建一个 RestTemplate 类型的 bean 并将其注入您的 Service bean(它很可能已经创建 - 取决于您使用的 Spring MVC 版本).

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).

一旦你有了它,那么两个 RestTemplates:一个在你的 Service bean 和一个注入到 FeatureFlipperManagerTest 将是相同的,并使用 MockRestServiceServer 将是可能的.

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:

将您的 Service 类修改为:

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

和你的测试类:

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

如果这失败并出现异常说没有 RestTemplate bean 存在,那么请粘贴有关您正在使用的 Spring(Spring Boot?)版本的信息.

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.

相关文章