PowerMock 与 EasyMock,期望 returns null 而不是模拟
PowerMock with EasyMock, expectation returns null instead of a mock
寻找一些关于为什么期望 returns null 而不是请求的模拟的指导。有问题的模拟是 Future 并且遵循与正确返回的其他模拟相同的模式。
为了向具有 powermock 和 easymock 经验的人提供所有信息,我提供了所有代码,包括被测代码和设置模拟和行为的测试代码。有问题的期望是
EasyMock.expect( mockAsyncClient.execute( EasyMock.isA( HttpGet.class ),
EasyMOck.isA( HttpClientContext.class ), isNull() ).andReturn( mockFuture )
它产生一个 null 而不是返回一个模拟的 Future。
如有任何想法,我们将不胜感激。
p.s。测试此功能需要大量模拟设置,我希望这不会妨碍评估问题。任何删除不必要的模拟基础设施的建议都将不胜感激。
这是测试中的代码
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 );
}
}
测试代码:
@Test
@PrepareOnlyThisForTest( { HttpAsyncClients.class, HttpAsyncClientBuilder.class } )
public void testGetResponseCallsResponseHandler()
throws IOException, InterruptedException, ExecutionException
{
// create mocks to be used when exercising the code under test
CloseableHttpAsyncClient mockAsyncClient =
EasyMock.createMock( CloseableHttpAsyncClient.class );
PowerMock.mockStatic( HttpAsyncClients.class );
HttpAsyncClientBuilder mockClientBuilder =
PowerMock.createMock( HttpAsyncClientBuilder.class );
HttpAsyncClientBuilder mockClientBuilder2 =
PowerMock.createMock( HttpAsyncClientBuilder.class );
HttpResponse mockResponse = PowerMock.createMock( HttpResponse.class );
StatusLine mockStatusLine = PowerMock.createMock( StatusLine.class );
@SuppressWarnings( "unchecked" )
Future<HttpResponse> mockFuture = PowerMock.createMock( Future.class );
// set up expectations that use the mocks
EasyMock.expect( HttpAsyncClients.custom() ).andReturn( mockClientBuilder );
EasyMock.expect( mockClientBuilder.setConnectionManager( EasyMock.isA( NHttpClientConnectionManager.class ) ) )
.andReturn( mockClientBuilder2 );
EasyMock.expect( mockClientBuilder2.build() ).andReturn( mockAsyncClient );
mockAsyncClient.start();
EasyMock.expectLastCall().once();
EasyMock.expect( mockAsyncClient.execute( EasyMock.isA( HttpGet.class ),
EasyMock.isA( HttpClientContext.class ),
EasyMock.isNull() ) )
.andReturn( mockFuture );
EasyMock.expect( mockFuture.get() ).andReturn( mockResponse );
EasyMock.expect( mockResponse.getStatusLine() ).andReturn( mockStatusLine );
EasyMock.expect( mockStatusLine.getStatusCode() ).andReturn( 200 );
mockAsyncClient.close();
EasyMock.expectLastCall().once();
PowerMock.replayAll();
ClientConfig cfg = new ClientConfigBuilder().build();
RestClient client = new RestClient( cfg );
int statusCode = client.getResponse( new ResponseHandler<Integer>() {
@Override
public Integer handleResponse( HttpResponse response )
throws ClientProtocolException, IOException
{
StatusLine statusLine = response.getStatusLine();
return statusLine.getStatusCode();
}
} );
PowerMock.verifyAll();
assertEquals( "status code incorrect", 200, statusCode );
}
我发现了这个问题,我相信这是其中一个问题,我肯定已经遇到了许多其他问题...
返回 null 的 mock 可以用我错误地使用 EasyMock 而不是 PowerMock 创建 mock 来解释:
CloseableHttpAsyncClient mockAsyncClient =
EasyMock.createMock( CloseableHttpAsyncClient.class );
将该行更改为
CloseableHttpAsyncClient mockAsyncClient =
PowerMock.createMock( CloseableHttpAsyncClient.class );
测试通过。
原因是 PowerMock 拥有它用于创建的模拟,并且只能验证这些模拟的行为。 PowerMock 包装了 EasyMock,因此需要了解受控制的模拟。
对于受此问题影响的人,请对问题进行投票。不知道为什么我被否决了,但请让这个答案更容易被发现。
谢谢,罗宾。
我之所以来到这里,是因为我试图 whenNew(SomeClass.class).withAnyArguments()
在 class 上,例如:
class SomeClass {
public SomeClass(String... args) { }
}
原来 withAnyArguments()
不匹配可变参数。在我的例子中,修复是:
whenNew(SomeClass.class).withArguments(Matchers.<String>anyVararg()).thenReturn(myMock);
寻找一些关于为什么期望 returns null 而不是请求的模拟的指导。有问题的模拟是 Future 并且遵循与正确返回的其他模拟相同的模式。
为了向具有 powermock 和 easymock 经验的人提供所有信息,我提供了所有代码,包括被测代码和设置模拟和行为的测试代码。有问题的期望是
EasyMock.expect( mockAsyncClient.execute( EasyMock.isA( HttpGet.class ),
EasyMOck.isA( HttpClientContext.class ), isNull() ).andReturn( mockFuture )
它产生一个 null 而不是返回一个模拟的 Future。
如有任何想法,我们将不胜感激。
p.s。测试此功能需要大量模拟设置,我希望这不会妨碍评估问题。任何删除不必要的模拟基础设施的建议都将不胜感激。
这是测试中的代码
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 );
}
}
测试代码:
@Test
@PrepareOnlyThisForTest( { HttpAsyncClients.class, HttpAsyncClientBuilder.class } )
public void testGetResponseCallsResponseHandler()
throws IOException, InterruptedException, ExecutionException
{
// create mocks to be used when exercising the code under test
CloseableHttpAsyncClient mockAsyncClient =
EasyMock.createMock( CloseableHttpAsyncClient.class );
PowerMock.mockStatic( HttpAsyncClients.class );
HttpAsyncClientBuilder mockClientBuilder =
PowerMock.createMock( HttpAsyncClientBuilder.class );
HttpAsyncClientBuilder mockClientBuilder2 =
PowerMock.createMock( HttpAsyncClientBuilder.class );
HttpResponse mockResponse = PowerMock.createMock( HttpResponse.class );
StatusLine mockStatusLine = PowerMock.createMock( StatusLine.class );
@SuppressWarnings( "unchecked" )
Future<HttpResponse> mockFuture = PowerMock.createMock( Future.class );
// set up expectations that use the mocks
EasyMock.expect( HttpAsyncClients.custom() ).andReturn( mockClientBuilder );
EasyMock.expect( mockClientBuilder.setConnectionManager( EasyMock.isA( NHttpClientConnectionManager.class ) ) )
.andReturn( mockClientBuilder2 );
EasyMock.expect( mockClientBuilder2.build() ).andReturn( mockAsyncClient );
mockAsyncClient.start();
EasyMock.expectLastCall().once();
EasyMock.expect( mockAsyncClient.execute( EasyMock.isA( HttpGet.class ),
EasyMock.isA( HttpClientContext.class ),
EasyMock.isNull() ) )
.andReturn( mockFuture );
EasyMock.expect( mockFuture.get() ).andReturn( mockResponse );
EasyMock.expect( mockResponse.getStatusLine() ).andReturn( mockStatusLine );
EasyMock.expect( mockStatusLine.getStatusCode() ).andReturn( 200 );
mockAsyncClient.close();
EasyMock.expectLastCall().once();
PowerMock.replayAll();
ClientConfig cfg = new ClientConfigBuilder().build();
RestClient client = new RestClient( cfg );
int statusCode = client.getResponse( new ResponseHandler<Integer>() {
@Override
public Integer handleResponse( HttpResponse response )
throws ClientProtocolException, IOException
{
StatusLine statusLine = response.getStatusLine();
return statusLine.getStatusCode();
}
} );
PowerMock.verifyAll();
assertEquals( "status code incorrect", 200, statusCode );
}
我发现了这个问题,我相信这是其中一个问题,我肯定已经遇到了许多其他问题...
返回 null 的 mock 可以用我错误地使用 EasyMock 而不是 PowerMock 创建 mock 来解释:
CloseableHttpAsyncClient mockAsyncClient =
EasyMock.createMock( CloseableHttpAsyncClient.class );
将该行更改为
CloseableHttpAsyncClient mockAsyncClient =
PowerMock.createMock( CloseableHttpAsyncClient.class );
测试通过。
原因是 PowerMock 拥有它用于创建的模拟,并且只能验证这些模拟的行为。 PowerMock 包装了 EasyMock,因此需要了解受控制的模拟。
对于受此问题影响的人,请对问题进行投票。不知道为什么我被否决了,但请让这个答案更容易被发现。
谢谢,罗宾。
我之所以来到这里,是因为我试图 whenNew(SomeClass.class).withAnyArguments()
在 class 上,例如:
class SomeClass {
public SomeClass(String... args) { }
}
原来 withAnyArguments()
不匹配可变参数。在我的例子中,修复是:
whenNew(SomeClass.class).withArguments(Matchers.<String>anyVararg()).thenReturn(myMock);