2016-04-26 30 views
2

我想測試一個API調用安排在正確的調度程序,並觀察主線程。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()); 
    } 
} 

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

拋出以下異常,並我不明白爲什麼,因爲productObservable是一個模擬。任何想法或類似的經驗?

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

你試過一個匹配器,即當(productsObservable.subscribeOn(任何(Scheduler.class))),或者一個捕手? – AndreLDM

+0

是的,我做了並獲得了相同的錯誤 – znat

+0

你可以試試'doReturn()。when()'語法,有時它可以解決類似你的問題嗎? – 2016-04-26 16:50:47

回答

2

問題是由於Observable :: subscribeOn是最終的方法,其中Mockito can't mock。 一個可能的解決方案是使用Powermock:

@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

謝謝。我的錯誤是使用Mockito.mock事件,儘管我使用了PowerMockRunner – znat