1

私はアンドロイドテストでは新しく、問題に遭遇しています。私はRxJavaを使用しており、UIをテストするためにIdlingResourceを使用しています。アイドリング中のリソースはビジーですが、UIをテストすることはできません。リソースの空き時間が空いている間にUIをテストしてください。

例:ボタンがあります。 onClickリクエストをしています。ボタンの要求中は無効になります。要求後、ボタンは有効状態になります。私は、次の3つの手順をテストしたい:

  1. ボタンが要求している間は無効になって要求
  2. ボタンの前に有効になっているが(onclickの)
  3. ボタンが要求終了し、応答メッセージが返されたときに有効になっている

あなたがこの問題で私を助けることができるなら、私は非常に幸せになるでしょう...

私の問題についてのさらなる情報が必要な場合は、それを教えてください。投稿を編集します

答えて

2

私が理解したように、あなたはあなたのUIをテストしようとしています。もしそうなら、正しい方法でそれを行うことを確認してください。

1)。あなたはしませんREALリクエスト。

は、あなたのテストはいつも似たような状況で同じ動作を持っていなければならないことを、ご了承ください。言い換えれば、それは同じ結果を与える必要があります、あなたは同じ入力パラメータを渡しています。
現在の入力パラメータ:
1.1)。ボタンは要求前に有効になります
1.2)。要求時にボタンが無効になりました
1.3)。リクエスト後にボタンを有効にする

このリストからわかるように、実際のリクエストは必要ありません。あなたがどんなサーバーを返すかは問題ではありません(エラーまたは成功)。あなたはこれのためにサーバーを必要としません。あなたが必要とするものは、まさに「何か」であり、実際のサーバーのように動作します。つまり、APIクライアントをモックする必要があります。

あなたは改造をしていると思います。そうでない場合は、クライアント用にinterfaceラッパーを作成する必要があります。換装を使用している場合は、interfaceをモックするだけです。

public interface ApiClient{ 
    @GET("/items") 
    Observable<MyResponse> doSomeRequest(); 
} 

をあなたは通常、あなたのAPIクライアントを作成するにはどうすればよい::

あなたは次のinterfaceを持っている、のは、仮定しよう

Retrofit retrofit = new Retrofit.Builder() 
    .baseUrl("https://api.github.com/") 
    .build(); 

ApiClient service = retrofit.create(ApiClient.class); 

あなたはテストでそれを行う必要があります方法:

import static org.mockito.Mockito.*; 

試験方法:

ApiClient apiMock = mock(ApiClient.class); 
when(apiMock.doSomeRequest()) 
       .thenReturn(Observable.just(fakeResponse)); 

または

ApiClient apiMock = mock(ApiClient.class); 
when(apiMock.doSomeRequest()) 
       .thenReturn(Observable.defer(new Func0<Observable<MyResponse>>() { 
         @Override 
         public Observable<MyResponse> call() { 
          try{ 
           Thread.sleep(2 * 1000) //2 seconds 
          }catch(Exception e){ 
           return Observable.error(e); 
          } 
          return Observable.just(fakeResponse); 
         } 
        })); 

P.S. Retrofitは、デフォルトでObservableのすべてに.subscribeOn(Schedulers.io())を追加します。この嘲笑されたオブジェクトはそれをしません。そう、それは次のようになります上記のコード内で.subscribeOn(Schedulers.io())を追加、またはコードでObservable.defer(...)
の結果に適用することを忘れないでください:

when(apiMock.doSomeRequest()) 
    .thenReturn(Observable.defer(...).subscribeOn(Schedulers.io())); 

そして、あなたはapiMockからActivity/Fragmentを渡すべきかあなたはテストしようとします。
どうすればいいですか? #2を参照してください。

2)。 DI(依存性注入)を使用

私はそれについてたくさん書くつもりはありません。
私はちょうどあなたが生産のための本当のimplementaionsを使用することができたときに、方法でプロジェクトを整理し、テスト用のモック実装する方法を、http://google.github.io/dagger/

、特に上のドキュメントを読むためにあなたをお勧め:

http://google.github.io/dagger/testing.html

言い換えれば、使用のためにアプリケーションをビルドするときには、実際の依存関係を提供します(実際の実装はApiClientです)。UIやビジネスロジックをテストするときは、モックの依存関係を渡しますあなたのテスト前に指定された動作を持っています。

これはすべて、私があなたに伝えたいことです。これが助けてくれることを願って、あなたに他の質問があれば教えてください。

1

Alexander's answerに小さい。私はSubjectを "嘲笑された" APIに使用します。これにより、実行を制御することができます。

//setup your test 
Subject<Response,Response> stubResponse = AsyncSubject.create(); 
ApiClient apiMock = mock(ApiClient.class); 
when(apiMock.doSomeRequest()).thenReturn(stubResponse.asObservable()); 
//check first condition that button is enabled before executing action 
//click on button 
//test your second condition that button is disabled while waiting for response 
stubResponse.onNext(fakeResponse); //return fake response 
stubResponse.onCompleted(); 
//test your third condition that button is enabled when you get response back 

備考。あなたのテストではsleepを使用しないでください。それはあなたのテストを遅くし、フレークさを追加します。

+0

ありがとうございました。それは理にかなっている – Alexander

関連する問題