如何模拟REST请求

时间:2017-06-30 14:01:56

标签: java spring junit mockito

我在JUnit中使用Mockito,我有一个方法使用 RestTemplate 向微服务发出请求。

private static final String REQUESTOR_API_HOST = "http://localhost:8090/requestor/v1/requestors/";

public TokenRequestorPayload getTokenRequestor(Long id) {
    restClient = new RestTemplate();
    return restClient.getForObject(REQUESTOR_API_HOST + id, TokenRequestorPayload.class);
}

此方法返回一个JSON对象,该对象将在TokenRequestorPayload类中反序列化。

当我执行单元测试时,他们失败了,因为mock没有工作,我得到了一个 org.springframework.web.client.ResourceAccessException 。我怎么能模仿我的RestTemplate?

测试

RestTemplate restTemplate = Mockito.spy(RestTemplate.class);
Mockito.doReturn(this.tokenRequestorMockJson()).when(restTemplate).getForObject(Mockito.anyString(), Mockito.eq(TokenRequestorPayload.class));

错误

  

org.springframework.web.client.ResourceAccessException:I / O错误   GET请求" http://localhost:8090/requestor/v1/requestors/1":   连接被拒绝(连接被拒绝);嵌套异常是   java.net.ConnectException:连接被拒绝(连接被拒绝)

2 个答案:

答案 0 :(得分:2)

在测试中,您正在为RestTemplate的模拟实例定义行为,这很好。

RestTemplate restTemplate = Mockito.spy(RestTemplate.class);

但是,Class Under Test不会使用相同的实例,每次都会创建一个新的RestTemplate实例并使用该实例。

public TokenRequestorPayload getTokenRequestor(Long id, RestTemplate restClient) {
    restClient = new RestTemplate(); // it uses this instance, not the mock
    return restClient.getForObject(REQUESTOR_API_HOST + id, TokenRequestorPayload.class);
}

因此,您需要找到一种方法将mock实例引入getTokenRequestor()方法。

例如这可以通过将restClient转换为方法参数来实现:

public TokenRequestorPayload getTokenRequestor(Long id, RestTemplate restClient) {
    return restClient.getForObject(REQUESTOR_API_HOST + id, TokenRequestorPayload.class);
}

并且测试可能类似于:

@Test
public void test() {
    RestTemplate restTemplateMock = Mockito.spy(RestTemplate.class);
    Mockito.doReturn(null).when(restTemplateMock).getForObject(Mockito.anyString(), Mockito.eq(TokenRequestorPayload.class));

    // more code

    instance.getTokenRequestor(id, restTemplateMock); // passing in the mock
}

答案 1 :(得分:1)

使用Spring对RestTemplate的嘲弄支持,而不是试图模拟RestTemplate - 更好:

创建一个模拟休息服务服务器,将其绑定到您的RestTemplate:

MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);

记录对该模拟服务器的调用,例如

  mockServer.expect(requestTo("some url").andExpect(method(HttpMethod.POST))
                .andRespond(withSuccess("addSuccessResult", MediaType.TEXT_PLAIN));

然后验证已经调用了模拟:

mockServer.verify();

请参阅https://objectpartners.com/2013/01/09/rest-client-testing-with-mockrestserviceserver/