2017-01-17 7 views
3

Completableは、例えば、私のテストでに加入されている場合、私はトラブルの識別を持っている:私のテストで(RxJava2)

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) }) 
    } 
} 

そしてを:

このテストに合格します。しかし、私はこのようflatMapCompletableを使用せずに同期する方法を書き換えるでした:

public Completable sync() { 
     return webApi.download() 
      .doOnNext((Data data) -> { repository.insert(data) }) 
      .ignoreElements(); 
    } 

をそれから私のテストに合格だろうが、コードは動作しませんでも私はinsertメソッドと呼ばれてきたと思ったので、私はそれにsubscribe()と呼ばれていませんでした。

どうすればよいですか?

私は私が知っているのが大好きだベストプラクティスを使用していないので、もし私がRxJavaに新しいですPS :)

更新

はマキシムOstrovidov

によって指さ .ingnoreElements()を呼び出していないの間違いを修正しました
+1

'flatMapCompletable'には何も問題はありませんでした。方法。 – akarnokd

+0

@akarnokdええ、私はそれが実際にはるかに好ましいと思うが、誰かが何らかの理由で観察可能なものを購読していない方法の1つに変更した場合、テストは失敗するはずだと私は信じています –

答えて

2

あなたは便宜上つけtest()演算子を使用することができます。

SyncService service = new SyncService(webApi, repository); 
TestObserver observer = service.sync().test(); 

しかし、私はこのようflatMapCompletableを使用せずに同期する方法を書き換えるでした:

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 
} 
doOnNextあなたが渡されたものに加入していないし、何も戻っていないので、 repository.insert(data)が呼び出されることはありません

//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) }) 
} 
によって放出される渡さ Completable使用して項目に0

flatMapCompletable購読:

.flatMapCompletable(new Function<Data, CompletableSource>() { 
    @Override 
    public CompletableSource apply(Data data) throws Exception { 
     return repository.insert(data); 
    } 
}) 

編集

あなたが適用さdoOnSubscribeで別のTestObserverCompletableを使用することができますrepository.insertサブスクリプションの事実をテストするには:

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(); 
+0

答えをありがとう!!既に更新された 'ignoreElements'を呼び出すのを忘れました。私はテストオペレータについて知らなかった、それは素晴らしいです! 'flatMapCompletable'が最良のアプローチだと私は同意しますが、誰かが' doOnNext'が購読すると思う間違いをした場合にテストが中断するようにしたいと思います。あなたが知っている解決策は? –

+0

私の回答を更新しました –

+0

ありがとう!!それはまさに私が探していたものでした! –

関連する問題