单元测试RxJava doOnSubscribe和doFinally

时间:2018-02-26 03:10:32

标签: unit-testing testing rx-java2

如何创建单元测试,以便在rxjava链的doOnScubscribedoFinally上完成某个副作用?

例如:

Observable.requestSomeValueFromWeb()
            .doOnSubscribe(() -> showLoading = true)
            .doFinally(() -> showLoading = false)
            .subscribe(result -> doSomething(result), error -> doErrorHandling(error));

如何在上面的场景中测试,showLoading在订阅时设置为true,而在observable处理时设置为false?

TestSubscriber<WebServiceResponse> loginRequestSubscriber = new TestSubscriber<>();

clientLoginViewModel.requestLogin().subscribe(loginRequestSubscriber);

// check that showLoading was true when webservice was called
assertEquals(true, showLoading);

// check that showLoading was false when webservice was finished
assertEquals(false, showLoading);

loginRequestSubscriber.assertSubscribed();

1 个答案:

答案 0 :(得分:1)

  

如果我理解正确,您的被测对象就是ClientLoginViewModel,所以我试图在那里工作。如果我弄错了,请告诉我,我可以重温我的回答:

系统中的类:

interface WebServiceResponse { } // We don't care about this here

interface Network {
    // This is whatever interacts with the Network, and we'll mock it out
    Single<WebServiceResponse> requestSomeValue();
}

// The class we are testing
class ClientLoginViewModel {

    final Network mNetwork;

    // This is the field we want to check... you probably want to make it
    // private and have accessors for it
    boolean showLoading;

    // This allows dependency injection, so we can mock :)
    ClientLoginViewModel(final Network network) {
        mNetwork = network;
    }

    // The actual method to test!
    Single<WebServiceResponse> requestLogin() {
        return mNetwork.requestSomeValue()
                .doOnSubscribe(disposable -> showLoading = true)
                .doFinally(() -> showLoading = false);
    }

}

现在测试!!!

class ClientLoginViewModelTest {

    @Test
    public void testLoading() {
        final Network network = mock(Network.class);
        final WebServiceResponse response = mock(WebServiceResponse.class);

        // This is the trick! We'll use it to allow us to assert anything
        // before the stream is done
        final PublishSubject<Boolean> delayer = PublishSubject.create();
        when(network.requestSomeValue())
            .thenReturn(
                   Single.just(response).delaySubscription(publishSubject)
            );

        final ClientLoginViewModel clientLoginViewModel = new ClientLoginViewModel(network);

        clientLoginViewModel
            .requestLogin()
            .test();

        // check that showLoading was true when webservice was called
        assertEquals(true, clientLoginViewModel.showLoading);

        // now let the response from the Network continue
        publishSubject.onComplete();

        // check that showLoading was false when webservice was finished
        assertEquals(false, clientLoginViewModel.showLoading);
    }
}