2015-12-17 5 views
10

Bit eines komplizierten Aufbau. Robolectric, PowerMockito Regel-basierte Konfiguration.PowerMockito: NotAMockException auf einem Mock

@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 Routine sein. Aber wenn ich versuche, verify auf einem dieser „Rückruf“ Mock-Instanzen zu nennen, 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 klar und offensichtlich wurde „enhanced“ durch Mockito und PowerMock kein() -Methode hat verifizieren statt Mockito.verify() zu verwenden ... was ist passiert?

EDIT: das ist in mancher Hinsicht mehr und in gewisser Weise weniger verwirrend.

Ich bin im Prozess einen anderen Test-Klasse zu bauen 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); 
    } 
} 
+0

Hier würden Sie Antwort finden: http://stackoverflow.com/questions/29611893/mockito-notamockexception – piotrek1543

+0

Sie werden detaillierter sein. Der Punkt der Frage ist, dass es * ist * ein Modell, wie es deutlich in den Klassennamen in der Stack-Trace angezeigt: 'ServiceCallbackBase $$ EnhancerByMockitoWithCGLIB $$ 9acf906b' –

Antwort

11

ich Ihr Beispiel nicht bauen kann, aber ich es geschafft, diese Minitest zu schreiben, die ein sehr ähnliches Problem ergibt:

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

(Beachten Sie die Mockito.withSettings(), ich weiß nicht warum, aber das macht die Prüfung nicht bestanden)

Drucke:

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! 
    ...... 

Nun, das sieht absolut als classloading Problem, Mockito vergleicht ServiceCallbackBase $$ EnhancerByMockitoWithCGLIB $$ etc .. loaded von PowerMock mit derselben durch Robolectric geladen (natürlich Rückkehr falsch in diesem Vergleich)

Dann schaffte ich die Testarbeit einfaches Hinzufügen "org.powermock.*" die Linie @PowerMockIgnore... dies zu machen:

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

Diese einfache Änderung mein Test zur Arbeit, und ich hoffe wirklich, dass das auch dir gefällt.

+0

Ich kann Ihnen genug upvotes dafür nicht geben. Ich weiß nicht warum, aber das hat es behoben. Vielen Dank! –

+0

Ich bin froh. Bitte! – fonkap

+1

Ich hatte das gleiche Problem und dies wurde vorerst behoben. Achten Sie aber, dass Sie fügen Sie '„org.powermock. *“' Auf die 'PowerMockIgnore' Anmerkung auf ** ** jeder Testklasse – andy9775

Verwandte Themen