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

时间:2017-02-13 16:30:57

标签: android unit-testing mockito

在此方法中,我想模拟并确保在我不传递某个电子邮件字符串时调用mSharedPrefsManager

@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("certain@email.com"))
                    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("certain@email.com", welcomePresenter);
        verify(retrieveInteractor).buildRetrieveRequest(eq("certain@email.com"), any(RetrieveImpl.OnRetrieveCompletedListener.class));
        verify(sharedPrefsManager).storePoints(any(Integer.class));
        verify(welcomePresenter).updateSilhouette(any(MaitreBaseGson.class));
    }
}

2 个答案:

答案 0 :(得分:0)

你在嘲笑:

soup = BeautifulSoup(el.text, 'html5lib')

这意味着当你调用@Mock RetrieveImpl retrieveInteractor; 时,不会调用真正的实现,并且最终不会调用你希望在该方法调用中调用的方法。

尝试使用@Spy,这实际上允许调用实际实现,您也可以验证该对象:

retrieveInteractor.buildRetrieveRequest(..)

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

我认为应该对RetrieveImpl.OnRetrieveCompletedListener类进行该测试。不是你问题中的那个。

但那只是我的口味..

答案 1 :(得分:0)

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