如何使用Mockito的doAnswer测试void方法

时间:2019-01-15 02:32:08

标签: android junit mockito

我是Mockito的新手,他试图了解如何使用doAnswer来测试 void 方法。

这是我的班级,采用onDestroy方法进行测试:

public class TPresenter implements TContract.Presenter {
    private CompositeSubscription viewSubscription;

    //.......

    @Override public void onCreate(.......) {
        this.viewSubscription = new CompositeSubscription();
        //.......
    }

    @Override public void onDestroy() {
        if(viewSubscription != null && !viewSubscription.isUnsubscribed()) {
            viewSubscription.unsubscribe();
    }
}

现在,我想为onDestroy()编写一个测试,以验证执行onDestroy后该订阅是否已取消订阅。我发现了几个使用doAnswer测试 void 方法的示例,例如herehere,但我不理解它们。

请说明如何测试方法onDestroy

3 个答案:

答案 0 :(得分:2)

测试onDestroy()的正常方法是基于viewSubscription是模拟对象。然后您将执行以下操作:

@Test
public testOnDestroyWithoutUnsubscribe() {
  when(mockedSubscription.isUnsubscribed()).thenReturn(false);
  //... trigger onDestroy()
  verifyNoMoreInteractions(mockedSubscription);
}

@Test
public testOnDestroyWithUnsubscribe() {
  when(mockedSubscription.isUnsubscribed()).thenReturn(true);
  //... trigger onDestroy()
  verify
  verify(mockedSubscription, times(1)).unsubscribe();
}

换句话说:创建一个模拟对象,并将其配置为采用两条可能的路径。然后,您验证是否已执行预期的操作(或没有,这就是第一个测试用例所做的事情:确保您不退订)。

当然,您不能测试“订阅对象为空”的情况(除了使其为空之外,并确保在触发onDestroy()时不会抛出NPE!

给出OP的评论:这里不必一定要使用嘲笑。但是,当您要测试void方法时,您的选择就非常有限。您必须以某种方式观察副作用!

如果您可以获得一个非模拟的viewSubscription实例来执行此操作,那就可以了。但是,如果没有,那么以某种方式插入模拟实例是您的下一个最佳选择。如何进行“依赖注入”取决于确切的上下文,例如您正在使用的模拟/测试框架。

答案 1 :(得分:0)

在测试中的主类中测试void方法不是问题,因为不需要doAnswer。

这是一个示例,您可以如何测试取消订阅的呼叫。


import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


@RunWith(MockitoJUnitRunner.class)
public class TPresenterTest {

    @InjectMocks
    private TPresenter target = new TPresenter();

    @Mock
    private CompositeSubscription viewSubscription;


    @Test
    public void onDestroyShouldUnsubscribeWhenSubscriptionNotNullAndUnsubscribed() {
        when(viewSubscription.isUnsubscribed()).thenReturn(false);

        target.onDestroy();

        verify(viewSubscription).unsubscribe();
    }

    @Test
    public void onDestroyShouldNotUnsubscribeWhenSubscriptionNotNullAndNotUnsubscribed() {
        when(viewSubscription.isUnsubscribed()).thenReturn(true);

        target.onDestroy();

        verify(viewSubscription, never()).unsubscribe();
    }
}

答案 2 :(得分:0)

正如我在对@GhostCat答案的评论中提到的那样,由于CompositeSubscription类的“新”实例,我的示例实际上是不可测试的。我将不得不对其进行重构,并且@GhostCat对他/她的答案的评论显示了一种实现方法。