Java 使用EasyMock的PowerMock,预期返回null而不是mock

Java 使用EasyMock的PowerMock,预期返回null而不是mock,java,unit-testing,powermock,easymock,Java,Unit Testing,Powermock,Easymock,寻找一些关于为什么期望返回null而不是请求的mock的指导。讨论中的mock是一个未来,它遵循与正确返回的其他mock相同的模式 为了向有powermock和easymock经验的人提供所有信息,我包含了所有代码,包括测试中的代码和设置模拟和行为的测试代码。所讨论的期望是 EasyMock.expect( mockAsyncClient.execute( EasyMock.isA( HttpGet.class ), EasyMOck.isA( HttpClientContext.class )

寻找一些关于为什么期望返回null而不是请求的mock的指导。讨论中的mock是一个未来,它遵循与正确返回的其他mock相同的模式

为了向有powermock和easymock经验的人提供所有信息,我包含了所有代码,包括测试中的代码和设置模拟和行为的测试代码。所讨论的期望是

EasyMock.expect( mockAsyncClient.execute( EasyMock.isA( HttpGet.class ),
EasyMOck.isA( HttpClientContext.class ), isNull() ).andReturn( mockFuture )
它生成一个空值,而不是返回一个模拟的未来

任何想法都将不胜感激

p、 测试这个函数需要大量的模拟设置,我希望这不会妨碍对问题的评估。任何删除不必要的模拟基础设施的建议都将不胜感激

下面是正在测试的代码

    public <T> T getResponse( ResponseHandler<T> responseHandler )
    throws IOException, InterruptedException, ExecutionException
{
    String connectTo = buildUri();

    try( CloseableHttpAsyncClient httpClient =
                                             HttpAsyncClients.custom()
                                                             .setConnectionManager( connManager )
                                                             .build() ) {
        HttpGet request = new HttpGet( connectTo );
        HttpClientContext ctx = HttpClientContext.create();

        addHeaders( request );

        httpClient.start();

        Future<HttpResponse> futureResponse = httpClient.execute( request, ctx, null ); //<-- this line executes using a verified HttpClient mock but returns null

        HttpResponse response = futureResponse.get();

        return responseHandler.handleResponse( response );
    }
}
public T getResponse(ResponseHandler ResponseHandler)
抛出IOException、InterruptedException、ExecutionException
{
字符串connectTo=buildUri();
try(CloseableHttpAsyncClient httpClient=
HttpAsyncClients.custom()
.setConnectionManager(连接管理器)
.build()){
HttpGet请求=新的HttpGet(连接到);
HttpClientContext ctx=HttpClientContext.create();
addHeaders(请求);
httpClient.start();

Future futureResponse=httpClient.execute(request,ctx,null);//我发现了这个问题,我确信这是其中一个问题,也影响了许多其他问题

返回null的mock可以解释为我错误地使用EasyMock创建mock而不是PowerMock:

CloseableHttpAsyncClient mockAsyncClient =
                                         EasyMock.createMock( CloseableHttpAsyncClient.class );
通过将该行更改为

CloseableHttpAsyncClient mockAsyncClient =
                                         PowerMock.createMock( CloseableHttpAsyncClient.class );
考试通过了

原因是PowerMock拥有它用来创建的模拟,并且只能验证这些模拟上的行为。PowerMock包装EasyMock,因此需要查看控制下的模拟

对于受此问题影响的人,请将问题向上投票。不确定我为什么被否决,但请让这个答案更容易发现


谢谢你,罗宾。

我发现了这个问题,我确信这是其中的一个问题,也影响了很多其他问题

返回null的mock可以解释为我错误地使用EasyMock创建mock而不是PowerMock:

CloseableHttpAsyncClient mockAsyncClient =
                                         EasyMock.createMock( CloseableHttpAsyncClient.class );
通过将该行更改为

CloseableHttpAsyncClient mockAsyncClient =
                                         PowerMock.createMock( CloseableHttpAsyncClient.class );
考试通过了

原因是PowerMock拥有它用来创建的模拟,并且只能验证这些模拟上的行为。PowerMock包装EasyMock,因此需要查看控制下的模拟

对于受此问题影响的人,请将问题向上投票。不确定我为什么被否决,但请让这个答案更容易发现


谢谢你,罗宾。

我在这里结束,因为我试图
whenNew(SomeClass.class)。在一个类上使用anyArguments()
,例如:

class SomeClass {
     public SomeClass(String... args) { }
}
原来
withAnyArguments()
与varargs不匹配。在我的情况下,修复程序是:

whenNew(SomeClass.class).withArguments(Matchers.<String>anyVararg()).thenReturn(myMock);
whenNew(SomeClass.class).withArguments(Matchers.anyVararg())。然后返回(myMock);

我在这里结束,因为我试图
在新的(SomeClass.class).withAnyArguments()
类上执行以下操作:

class SomeClass {
     public SomeClass(String... args) { }
}
原来
withAnyArguments()
与varargs不匹配。在我的情况下,修复程序是:

whenNew(SomeClass.class).withArguments(Matchers.<String>anyVararg()).thenReturn(myMock);
whenNew(SomeClass.class).withArguments(Matchers.anyVararg())。然后返回(myMock);

null通常在期望值不匹配时返回,这向我表明您的一些参数匹配器与您期望的不匹配。我建议将匹配器,看看这是否有帮助,然后你可以调试哪些不是你所期望的类型。另外,由于有很多模拟正在进行,你的其他一些期望可能不匹配并返回空值,所以调试并查看哪些变量为空也会有帮助。最后一个问题,connManager在哪里来自?感谢您的输入。connManager是由类在构造期间构建的真实类型。至于其他空值,我已经通过注释这些对未来的期望来验证一切都是好的。所有期望都得到满足,包括try with resources块中隐式的stop()调用。我将尝试anyObject()正如您所建议的。我尝试了anyObject()来代替isA(…),但它有相同的行为。还尝试了返回IAnswer(){},但没有调用answer()方法。顺便说一句,在非模拟集成测试期间,代码可以工作。测试了anyObject(),但行为是相同的。不过,为了使其编译,我必须强制转换第一个anyObject()引用HttpGet,因此期望值可以解析调用哪个重载方法。我感觉类型擦除可能导致EasyMock期望值失败。以前从未见过这种行为,模拟重载函数并不是什么新鲜事。EasyMock.expect(mockAsyncClient.execute(EasyMock.isA(HttpGet.class)),EasyMock.isA(HttpClientContext.class),EasyMock.isA(FutureCallback.class)).andReturn(mockFuture);结果:supprested:java.lang.IllegalStateException:前面的方法调用缺少行为定义:CloseableHttpAsyncClient.execute(获取HTTP/1.1,org.apache.HTTP.client.protocol)。HttpClientContext@63dda940,null)用法是:expect(a.foo())。andXXX()验证了execute()方法模拟与签名类型匹配。Powermock bug?除了从execute()方法返回的空引用外,该测试还未能满足此方法的预期:…抑制:java.lang.IllegalStateException:前面的方法调用缺少行为定义:CloseableHttpAsyncClient.execute(获取HTTP/1.1,org.apache.HTTP.client.protocol。HttpClientContext@edb83f8,xxx.RestClient