gpt4 book ai didi

android - PowerMockito:模拟的 NotAMockException

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:39:59 26 4
gpt4 key购买 nike

有点复杂的设置。 Robolectric,PowerMockito 基于规则的配置。

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
// Using "PrepareOnlyThis" prevents powermock from trying to instrument the whole hierarchy,
// part of which we've ignored (android.os.* in this case)
@PrepareOnlyThisForTest({ServiceCallbackBase.class}) // this class extends Handler,
// so we need PrepareOnlyThis. It also has some final methods we need to verify()
public class ServiceBaseTests {

private class Foo {
// nothing
}

@Rule
public PowerMockRule rule = new PowerMockRule();

private ServiceCallbackBase<Object, Foo> setupCallback( boolean hasValidContext, boolean allContextsCanceled ) {
ServiceCallbackBase<Object, Foo> callback = PowerMockito.mock( ServiceCallbackBase.class );
// EDIT: I have converted these to PowerMockito.doReturn()s to no avail.
PowerMockito.when( callback.hasValidContext() ).thenReturn( hasValidContext );
PowerMockito.when( callback.allContextsAreCanceled( any( Message.class ) ) ).thenReturn( allContextsCanceled );
PowerMockito.doNothing().when( callback ).preSendMessage( any( Message.class ) );
return callback;
}

应该很常规。但是每当我尝试在这些“回调”模拟实例之一上调用 verify 时,例如:

  private void test_notifyCallback( boolean isFromCache ) {
ServiceCallbackBase<Object, Foo> callback = setupCallback( true, false );

uut.addHandler( TestEnum.FOO, callback );
uut.addHandler( TestEnum.BAR, PowerMockito.mock( ServiceCallbackBase.class ) );
uut.addHandler( TestEnum.BAZ, PowerMockito.mock( ServiceCallbackBase.class ) );

Response<Foo> foo = new Response<>( new Foo(), new ResponseStatus( 0, "Error" ) );
uut.handleCallBack( TestEnum.FOO, foo, isFromCache );

ArgumentCaptor<Message> captor = ArgumentCaptor.forClass( Message.class );

// this line throws the error.
verify( callback ).preSendMessage( captor.capture() );

assertThat( captor.getValue().what ).isEqualTo( TestEnum.FOO.ordinal() );
assertThat( captor.getValue().obj ).isEqualTo( foo );
assertThat( captor.getValue().arg1 ).isEqualTo( isFromCache ? 1 : 0 );
}

我收到这样的错误:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to verify() is of type ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$9acf906b and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
verify(mock).someMethod();
verify(mock, times(10)).someMethod();
verify(mock, atLeastOnce()).someMethod();

它显然已经被 mockito“增强”了,而且 PowerMock 没有 verify() 方法来代替 Mockito.verify()... 是什么给了?

编辑:这在某些方面更容易混淆,而在某些方面则更少混淆。

我正在构建另一个测试类来测试 ServiceCallbackBase 本身。如果我从该类中删除测试,这些测试就会通过。不同类中的以下代码 fragment 导致上述测试失败。

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class ServiceCallbackBaseTests {

@Test
public void test_nothing(){

}

private ServiceCallbackBase<Object, String> uutSpy;


@Before
public void setup(){
uutSpy = mock( ServiceCallbackBase.class );
}
}

最佳答案

我无法构建您的示例,但我设法编写了这个产生非常相似问题的小型测试:

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
@PrepareOnlyThisForTest({ServiceCallbackBase.class, Dummy.class})
public class MainActivityTest {

@Rule
public PowerMockRule rule = new PowerMockRule();

@Test
public void test1() throws Exception {
try {
//This Mockito.withSettings() thing is important to make the test fail!
ServiceCallbackBase callback = PowerMockito.mock( ServiceCallbackBase.class, Mockito.withSettings());

callback.dispatchMessage(null);
Mockito.verify(callback).dispatchMessage(null);

} catch (Exception e){
e.printStackTrace();
Assert.fail();
}
}
}

(注意 Mockito.withSettings(),我不知道为什么会导致测试失败)

打印:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to verify() is of type ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$62776c54 and is not a mock!
Make sure you place the parenthesis correctly!
......

好吧,这绝对看起来是一个类加载问题,mockito 正在比较由 Powermock 加载的 ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$等..

然后,我设法使测试工作,只需将 "org.powermock.*" 添加到行 @PowerMockIgnore... 这是:

@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*", "org.powermock.*"})

这个简单的改变让我的测试成功了,我真的希望你的也能成功。

关于android - PowerMockito:模拟的 NotAMockException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34343601/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com