Java EasyMock正在调用real方法

Java EasyMock正在调用real方法,java,unit-testing,easymock,Java,Unit Testing,Easymock,我有一个测试用例: TestClient @RunWith(EasyMockRunner.class) public class TestClient extends EasyMockSupport { @TestSubject private final IClient client = new Client(); @Mock private HttpClient httpClient; @Mock private HttpUriReque

我有一个测试用例:

TestClient

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

}
客户端

@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(请求)。尝试移除它。您已经通过
expect(httpClient.execute(request)).andReturn(response)为
httpClient
设置了期望


您必须从中删除
final

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

你可以用它作为一个工具;但亲爱的我不


原始答复:

发布完整的堆栈跟踪以及
客户机
类的相关部分将有助于我们与您一起调试。你提到:

client.execute(请求)
I do
httpClient.execute(请求)

但是(至少在您发布的代码中,
client
没有任何地方可以获得对模拟的
httpClient
实例的引用。您的
Client
类是否可能构造自己的
HttpClient
实例,并针对该实例而不是模拟实例发出请求

如果是这样,您的
客户端
应该遵循该模式,在构建时传入一个
HttpClient
实例,而不是在内部构建一个实例


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

,在
Client.execute(请求)
I do
httpClient.execute(请求)
。为什么EasyMock需要知道
getURI
方法的响应?我对方法产生了期望。这不是嘲弄的重点?@user230137如果你发布
Client.execute()
;的内容,那会有所帮助;否则我们只能猜测。不是那样的。EasyMock未能注入我的模拟,因为该字段是最终字段,但失败了。模拟的
httpClient
将由EasyMock注入(这就是我使用
TestSubject
注释的原因)。我同意,如果我们不知道框架,它是不可见的。@user230137请包含您的
客户机
代码,以便我们可以看到它在做什么。如果您在
Client
中的任何位置调用
new HttpClient()
,即使EasyMock正在注入,也将使用该调用。我添加了客户端代码。当删除final时,它可以工作,但可能有一个解决方案。即使我在
Client.execute()
中调用
request.getURI()
,它也应该可以工作,因为它不会在方法被模拟时调用它。@user230137是的,问题是您的
final httpClient
实例变量。更新答案。