PowerMockito: NotAMockException auf einem Mock
Bit eines komplizierten Setups. Robolectric, PowerMockito regelbasierte Konfiguration.
@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;
}
Sollte ziemlich routinemäßig sein. Aber wann immer ich versuche, @ anzurufverify
auf einer dieser "Callback" -Mock-Instanzen, zum Beispiel:
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 );
}
Ich erhalte eine Fehlermeldung wie folgt:
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();
Es ist eindeutig und offensichtlich durch mockito "verbessert" worden, und PowerMock verfügt nicht über eine verify () -Methode, die anstelle von @ verwendet werden kanMockito.verify()
... was gibt
BEARBEITE: das ist in gewisser Hinsicht mehr und in gewisser Hinsicht weniger verwirrend.
Ich bin gerade dabei, eine weitere Testklasse zu erstellen, um ServiceCallbackBase selbst zu testen. Wenn ich die Tests aus dieser Klasse entferne, bestehen diese Tests. Das folgende Snippet in einer anderen Klasse führt dazu, dass die obigen Tests fehlschlagen.
@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 );
}
}