EasyMock 正在调用真正的方法

EasyMock is calling the real method

我有这个测试用例:

测试客户端

@RunWith(EasyMockRunner.class)
public class TestClient extends EasyMockSupport {

    @TestSubject
    private final IClient client = new Client();

    @Mock
    private HttpClient httpClient;

    @Mock
    private HttpUriRequest request;
    @Mock
    private HttpResponse response;

    @Test
    public void testExecute() throws ClientProtocolException, IOException {
        expect(httpClient.execute(request)).andReturn(response);
        replayAll();
        httpClient.execute(request);
        client.execute(request);
        verifyAll();
    }
}

客户端

public class Client implements IClient {

    private final HttpClient httpClient;

    public Client() {
        httpClient = createDefaultClient();
    }

    private HttpClient createDefaultClient() {
        return HttpClientBuilder.create()
                .build();
    }

    @Override
    public HttpResponse execute(final HttpUriRequest request)
            throws IOException {
        return httpClient.execute(request);
    }

}

当我 运行 它时,我得到这个错误:

Unexpected method call HttpUriRequest.getURI()

一般创建的不会调用这个方法。

为什么会出现这个错误?为什么它要求我为 getURI 方法定义一个结果?

我怀疑在方法 client.execute(request) 内部有一个 request.getURI() 语句(或深埋在被调用的方法中)。 Easy Mock 需要知道调用此方法时要给出的响应。

我怀疑问题出在httpClient.execute(request);的调用上。尝试将其删除。您已经通过 expect(httpClient.execute(request)).andReturn(response);.

设置了对 httpClient 的期望
@Test
public void testExecute() throws ClientProtocolException, IOException {
    expect(httpClient.execute(request)).andReturn(response);
    replayAll();
    client.execute(request);
    verifyAll();
}

您必须从

中删除 final
private final HttpClient httpClient;

否则 EasyMock 无法用自己的模拟实例覆盖您的 httpClient。当然更好的方法还是直接使用依赖注入,但这与你的实际问题无关。

可以使用reflection as a workaround;但亲爱的我不...


原回答:

发布完整的堆栈跟踪以及您的 Client class 的相关部分将帮助我们与您一起调试。你提到:

in client.execute(request) I do httpClient.execute(request).

但是(至少在您发布的代码中)client 没有任何地方获得对模拟的 httpClient 实例的引用。您的 Client class 是否构建了它自己的 HttpClient 实例,并针对 that 而不是您的 mock 发出请求?

如果是这样,您的 Client 应该遵循 dependency injection 模式并在构造时传入一个 HttpClient 实例,而不是在内部构造一个实例。

另一种可能性是您的 Client.execute() 方法在某个时刻调用了 request.getURI(),在这种情况下您只需要 expect() 调用 request.getURI().