如何在公共方法中测试私有Observable?

时间:2017-11-19 21:02:16

标签: android unit-testing mockito

我是测试的新手。

我有类似下一个代码的内容,并希望使用Mockito:

使用unitTests覆盖它
    public void doSomeJob(){
        //some code before
        getMvpView().execute(getObservable());
        //some code after
    }

    private Observable<Boolean> getObservable(){
        return Observable.create(new ObservableOnSubscribe<Boolean>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Boolean> e) throws Exception {
                Thread.sleep(5000);
                e.onNext(true);
                e.onComplete();
            }
        });
    }

所以问题:

  1. 使用Mokito对getMvpView().execute(getObservable());进行正确的写入测试?
  2. 如何验证getObservable()的结果?

2 个答案:

答案 0 :(得分:0)

如果您的私有方法不是界面的一部分,即无法从课外到达,那么您不应该测试它(可能不是,因为它是私有的)。 Mockito轮流doesn't provide mocking of private methods。因此,您需要更改界面(在外部提供此数据)或保留它而不进行测试。

答案 1 :(得分:0)

您应该测试的是调用正在测试的类的公共方法的效果。如果您这样做,您将能够在以后自由地重构实现细节,并且您的测试仍将验证您的类是否按预期工作。

我想你的代码是presenter实现的一部分,getMvpView()方法返回一个视图接口:

public class MvpPresenterImpl {

    private MvpView view;

    public void doSomeJob(){
        //some code before
        getMvpView().execute(getObservable());
        //some code after
    }

    public void attachView(MvpView view) {
        this.view = view;
    }

    private MvpView getMvpView() {
        return view;
    }

    private Observable<Boolean> getObservable(){
        return Observable.create(new ObservableOnSubscribe<Boolean>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Boolean> e) throws Exception {
                Thread.sleep(5000);
                e.onNext(true);
                e.onComplete();
            }
        });
    }
}

你可以测试doSomeJob()的效果:

public class MvpPresenterImplTest {

    private MvpPresenterImpl presenter;
    private MvpView mockView;

    @Before
    public void setUp() throws Exception {

        // Create a mock view instance so that we can verify method calls on it
        mockView = mock(MvpView.class);

        // Create our object under test, and set it up with the mock view
        presenter = new MvpPresenterImpl();
        presenter.attachView(mockView);
    }

    @Test
    public void doSomeJob_callsExecuteOnViewWithCorrectObserver() throws Exception {

        // What we want to test is the effect of invoking a public method.
        presenter.doSomeJob();

        // Verify that the execute method has been called by your class 
        // under test, and save the parameter for later.
        ArgumentCaptor<Observable<Boolean>> paramCaptor = 
            ArgumentCaptor.<Observable<Boolean>>forClass((Class)Observable.class);
        verify(mockView).execute(paramCaptor.capture());

        // Get the actual observable that the execute method was called with.
        Observable<Boolean> param = paramCaptor.getValue();

        // Get a test observer so that we can check what our Observable emits 
        // (TestObserver is a built-in feature of RxJava, not Mockito.)
        TestObserver<Boolean> test = param.test();

        // Assert that the Observable behaves as expected
        test.assertComplete();
        test.assertResult(true);
    }
}