[英]How to assert if a Completable has been subscribed/completed (RxJava2)
我無法確定我的測試中是否已訂閱Completable
,例如:
interface IWebApi {
Observable<Data> download();
}
interface IDataRepository {
Completable insert(Data data);
}
class SyncService {
IWebApi webApi;
IDataRepository repository;
public SyncService(IWebApi webApi, IDataRepository repository) {
this.webApi = webApi;
this.repository = repository;
}
public Completable sync() {
return webApi.download()
.flatMapCompletable((Data data) -> { repository.insert(data) })
}
}
然后在我的測試中:
@Test
public void syncTest() {
Data data = new Data();
IDataRepository repository = mock (IDataRepository.class);
IWebApi webApi = mock (IWebApi.class);
given(webApi.download()).willReturn(Observable.just(data));
given(repository.insert(data)).willReturn(Completable.complete());
TestObserver<Void> observer = new TestObserver<Void>();
SyncService service = new SyncService(webApi, repository);
service.sync()
.subscribe(observer);
observer.assertComplete();
verify(repository).insert(data);
}
這個測試將通過。 但是我可以在不使用flatMapCompletable
情況下重寫sync方法,如下所示:
public Completable sync() {
return webApi.download()
.doOnNext((Data data) -> { repository.insert(data) })
.ignoreElements();
}
然后我的測試會通過,但代碼不起作用,因為即使我認為我已經調用了insert方法,我也沒有在其中調用subscribe()
。
我該怎么辦呢?
PS我是RxJava的新手,所以如果我沒有使用最好的做法,我很想知道:)
更新
修正了Maxim Ostrovidov指出的不調用.ingnoreElements()
的錯誤
您可以使用test()
運算符:
SyncService service = new SyncService(webApi, repository);
TestObserver observer = service.sync().test();
但是我可以在不使用flatMapCompletable的情況下重寫sync方法,如下所示:
public Completable sync() {
return webApi.download()
.doOnNext((Data data) -> { repository.insert(data) })
}
這不會編譯,因為doOnNext
僅用於調用對項的操作,而不是更改流返回類型。 在你的情況下,方法期望Completable
但實際上它將是Observable<Data>
。
即使您強制更改最終的流類型:
public Completable sync() {
return webApi.download()
.doOnNext((Data data) -> { repository.insert(data) })
.ignoreElements(); //converts to Completable
}
repository.insert(data)
將不會被調用,因為doOnNext
沒有訂閱你傳遞的任何內容並且沒有返回任何內容:
//under the hood of lambdas
.doOnNext(new Consumer<Data>() {
@Override
public void accept(Data data) throws Exception {
}
})
您的初始代碼最適合您想要實現的目標:
public Completable sync() {
return webApi.download()
.flatMapCompletable((Data data) -> { repository.insert(data) })
}
flatMapCompletable
使用Observable
發出的項目訂閱傳遞的Completable
:
.flatMapCompletable(new Function<Data, CompletableSource>() {
@Override
public CompletableSource apply(Data data) throws Exception {
return repository.insert(data);
}
})
編輯
要測試repository.insert
訂閱的事實,您可以使用另一個TestObserver
和Completable
與應用的doOnSubscribe
:
TestObserver repositoryInsertObserver = TestObserver.create();
Completable insertCompletable = Completable.complete()
.doOnSubscribe(d -> repositoryInsertObserver.onSubscribe(d));
//pass completable to your mock
given(repository.insert(data)).willReturn(insertCompletable);
//and verify that subscription took place
repositoryInsertObserver.assertSubscribed();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.