2016-04-26 8 views
2

Ich versuche zu testen, dass ein API-Aufruf auf dem richtigen Scheduler geplant ist und auf dem Hauptthread beobachtet.Mockito - MissingMethodInvocationException

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Observable.class, AndroidSchedulers.class}) 
public class ProductsPresenterTest { 

    private ProductsPresenter presenter; 
    @Before 
    public void setUp() throws Exception{ 
     presenter = spy(new ProductsPresenter(mock(SoajsRxRestService.class))); 
    } 


    @Test 
    public void testShouldScheduleApiCall(){ 
     Observable productsObservable = mock(Observable.class); 
     CatalogSearchInput catalogSearchInput = mock(CatalogSearchInput.class); 
     when(presenter.soajs.getProducts(catalogSearchInput)).thenReturn(productsObservable); 

     /* error here*/ 
     when(productsObservable.subscribeOn(Schedulers.io())).thenReturn(productsObservable); 
     when(productsObservable.observeOn(AndroidSchedulers.mainThread())).thenReturn(productsObservable); 
     presenter.loadProducts(catalogSearchInput); 

     //verify if all methods in the chain are called with correct arguments 
     verify(presenter.soajs).getProducts(catalogSearchInput); 
     verify(productsObservable).subscribeOn(Schedulers.io()); 
     verify(productsObservable).observeOn(AndroidSchedulers.mainThread()); 
     verify(productsObservable).subscribe(Matchers.<Subscriber<Result<Catalog<SoajsProductPreview>>>>any()); 
    } 
} 

Die Linie

when(productsObservable.subscribeOn(Schedulers.io())).thenReturn(productsObservable); 

die folgende Ausnahme wirft, und Ich verstehe nicht, warum da productObservable ein Mock ist. Irgendeine Idee oder ähnliche Erfahrung?

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'. 
For example: 
    when(mock.getArticles()).thenReturn(articles); 

Also, this error might show up because: 
1. you stub either of: final/private/equals()/hashCode() methods. 
    Those methods *cannot* be stubbed/verified. 
    Mocking methods declared on non-public parent classes is not supported. 
2. inside when() you don't call method on mock but on some other object. 
+0

Haben Sie eine Matcher versucht, das heißt, wenn (productsObservable.subscribeOn (jeder (Scheduler.class))), oder vielleicht ein Captor? – AndreLDM

+0

Ja, ich habe und erhielt den gleichen Fehler – znat

+0

Können Sie versuchen, die 'doReturn(). When()' -Syntax, manchmal löst es Probleme wie Ihre? –

Antwort

2

Das Problem ist durch Observable :: subscribeOn eine letzte Methode ist, der Mockito can't mock. Eine mögliche Lösung ist PowerMock zu verwenden:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Observable.class) 
public class MockTest { 
    @Test 
    public void test() { 
     Observable productsObservable = PowerMockito.mock(Observable.class); 

     when(productsObservable.subscribeOn(null)).thenReturn(productsObservable); 
     productsObservable.subscribeOn(null); 
     verify(productsObservable).subscribeOn(null); 
    } 
} 
+0

Danke. Mein Fehler war, Mockito.mock zu verwenden, obwohl ich den PowerMockRunner benutzte – znat