如何在使用Mockito的方法中模拟和验证回调

问题描述:

在此方法中,我想模拟并确保mSharedPrefsManager在我不传入某个电子邮件字符串时被调用。如何在使用Mockito的方法中模拟和验证回调

@Override 
public void retrieveWithEmail(final String email, final WelcomeContract.Presenter presenter) 
{ 
    retrieveInteractor.buildRetrieveRequest(email, new RetrieveImpl.OnRetrieveCompletedListener() 
    { 
     @Override 
     public void onRetrieveCompleted(final MaitreBaseGson retrieveResponse, RetrieveImpl retrieveClass) 
     { 
      if (retrieveResponse.getStatus().equals(mContext.getString(R.string.ok))) 
      { 
       if (!email.equals("[email protected]")) 
        mSharedPrefsManager.storePoints(Integer.parseInt(retrieveResponse.getData().getPoints())); 
       presenter.updateSilhouette(retrieveResponse); 
      } 
      // Silently swallow failures 
     } 
    }); 
} 

但是,在我的测试中,我无法确定是否调用了mSharedPrefsManager。 Mockito说.storePoints()永远不会被调用。我想过要做一个doReturn().when(),但因为这是不可行的方法,是吗?

如何捕获sharedPrefsManager上的相互作用?

Mockito也说.updateSilhouette()不叫。我需要以某种方式模拟onRetrieveCompleted()

@RunWith(MockitoJUnitRunner.class) 
public class WelcomeInteractorTest 
{ 
    @Mock 
    RetrieveImpl retrieveInteractor; 

    @Mock 
    WelcomePresenter welcomePresenter; 

    @Mock 
    SharedPrefsManager sharedPrefsManager; 

    @Mock 
    Context context; 

    @InjectMocks WelcomeInteractorImpl welcomeInteractor; 

    @Mock 
    RetrieveImpl.OnRetrieveCompletedListener onRetrieveCompletedListener; 

    @Test 
    public void RetrieveWithCertainEmail_SavePoints() 
    { 
     welcomeInteractor.retrieveWithEmail("[email protected]", welcomePresenter); 
     verify(retrieveInteractor).buildRetrieveRequest(eq("[email protected]"), any(RetrieveImpl.OnRetrieveCompletedListener.class)); 
     verify(sharedPrefsManager).storePoints(any(Integer.class)); 
     verify(welcomePresenter).updateSilhouette(any(MaitreBaseGson.class)); 
    } 
} 
+0

你可以发布你如何结束你的代码? – Caique

尝试使用@Spy造成了很多的问题,我作为RetrieveImpl与网络进行交互。

我改为使用Captor并捕获回调。

@Captor 
private ArgumentCaptor<RetrieveImpl.OnRetrieveCompletedListener> mOnRetrieveCompletedListenerCaptor; 

... 

@Test 
public void isTest() 
{ 
    ... 
    verify(retrieveInteractor).buildRetrieveRequest(eq(email), mOnRetrieveCompletedListenerCaptor.capture()); 
    mOnRetrieveCompletedListenerCaptor.getValue().onRetrieveCompleted(mockMaitreBaseGsonSuccessful, retrieveInteractor); 
} 

你嘲讽:

@Mock 
RetrieveImpl retrieveInteractor; 

这意味着,当你调用retrieveInteractor.buildRetrieveRequest(..),真正实现不被调用,最终,你期望得到的是方法调用中调用的方法都不会被调用。 。

尝试使用@Spy代替,这实际上允许真正落实到被调用,您可以验证对象也:

@Spy 
RetrieveImpl retrieveInteractor; 

只有一方..在认为你在测试太多,并深入你的验证。

在我看来,测试应该为RetrieveImpl.OnRetrieveCompletedListener类完成。不是你问题中的问题。

但是那只是我的口味..

+0

我的'RetrieveImpl'将'Context'作为其构造函数的唯一参数,'Mockito'给我一个错误,说它需要一个0-arg构造函数。我可以以某种方式嘲笑'Context',还是需要遵循不同的方法? –

+1

添加一个默认构造函数,并为上下文设置器。然后模拟上下文并使用setter注入RetrieveImpl –