2017-01-18 5 views
0
@Override public void onBarcodeReceived(final String barcode) { 
    view.showProgress(); 
    if (!textUtil.isEmpty(barcode)) { 
     subscriptions.add(
      interactor.getSearchResultByBarcode(barcode).subscribe(subscriberForSearchResults(true))); 
    } 
    } 

    private Subscriber<PriceAndStockActivityViewModel> subscriberForSearchResults(
     boolean fromBarcode) { 
    return new BaseSubscriber<PriceAndStockActivityViewModel>() { 
     @Override public void onNext(PriceAndStockActivityViewModel priceAndStockActivityViewModel) { 
     super.onNext(priceAndStockActivityViewModel); 
     view.updateView(priceAndStockActivityViewModel); 
     } 

     @Override public void onError(Throwable e) { 
     super.onError(e); 
     view.hideProgress(); 
     view.organizeScreenComponentsByVisibility(true); 
     view.onError(e); 
     } 
    }; 
    } 

のためのユニットテストを書くためにどのように呼ばれるメソッドをテストしたいと思っていました はRxJava CompositeSubscription

@Test public void should_updateViewByViewModel_when_AnyBarcodeReceived() { 
    String barcode = "123123123"; 
    PriceAndStockActivityViewModel viewModel = getPriceAndStockActivityViewModel(barcode); 
    when(textUtil.isEmpty(barcode)).thenReturn(false); 
    when(interactor.getSearchResultByBarcode(anyString())).thenReturn(Observable.just(viewModel)); 

    presenter.onBarcodeReceived(barcode); 

    verify(view).showProgress(); 
    verify(interactor).getSearchResultByBarcode(anyString()); 
    verify(view).updateView(any(PriceAndStockActivityViewModel.class)); 
    } 

以下のようにonBarcodeReceived。シンプルに見えますが、解決方法を見つけることができませんでした。 updateViewを確認する方法はありますか?

+1

実際に私の実装は正しいが、私のために異なるエラーがあったので、この質問を議論の対象外としている。コードとの関係はありません。人々は赤を持つことを混乱させることがあります。それを削除してください。 –

答えて

0

別のスレッドが完了するのを待つために、このMockito機能を使用することができます:verify with timeout

verify(view, timeout(100)).updateView(any(PriceAndStockActivityViewModel.class)); 

それともCountDownLatchなどのスレッド同期のいくつかの手段を使用しています。 Mockito hereの例を参照してください。

+0

スレッド処理の問題だけではありません。私はrxjavaの問題があるはずだと信じています... –

+0

@MustafaGüvenタイムアウトを追加しようとしましたか?私はここでRxJavaに固有のことは何も見ません。 –

+0

はい追加しましたが機能しませんでした。 –

1

私はgetSearchResultByBarcode()がバックグラウンドスレッドで動作すると推定します。ですから、このバックグラウンドスレッドからあなたのUIをどのように変更できるのでしょうか?

私はあなたのsubscriberの実行をAndroidのメインスレッドに変更して、getSearchResultByBarcode()のスレッドが将来変更された場合でも、ビューを安全に操作できるようにしました。しかし、Schedulerを直接ハードコードするのではなく、コンストラクタなどを介してプレゼンタクラスに注入することができます。あなたが「本物」のプレゼンターを作成している場合は、当然、あなたはAndroidSchedulers.mainThread()に渡したい:

public MyPresenter(, Scheduler observeScheduler) { 
    ... 
    this.observeScheduler = observeScheduler; 
} 

.... 

@Override 
public void onBarcodeReceived(final String barcode) { 
    view.showProgress(); 
    if (!textUtil.isEmpty(barcode)) { 
      subscriptions.add(interactor.getSearchResultByBarcode(barcode) 
       .observeOn(observeScheduler) 
       .subscribe(subscriberForSearchResults(true))); 
    } 
} 

Presenterを構築するときにRxJava 1を使用している場合は、あなたのテストでは、あなたは(Schedulers.immediate()を使用すると思います。 xまたはSchedulers.trampoline()を使用している場合は、をユニットテストで使用しなくても動作するはずです。

そして1つの無関係あなたはandroid.text.TextUtilsの代わりにorg.apache.commons.lang3.StringUtilsを使うことができます - それはおおよそ同じ機能を持ちますが、あなたのユニットでそれをモックする必要はありませんテスト。