如何创建单元测试,以便在rxjava链的doOnScubscribe
和doFinally
上完成某个副作用?
例如:
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();
答案 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);
}
}