2017-04-07 17 views
1

私はandroid unit testsを書く方法を学んでいます。だから、私はこのような何かを見た:そして、私は例を見ていますRxJava Observablesをテストする方法を理解する

@Test 
public void getPopularMoviesMakesApiCall() { 
    // given that the api service returns a response 
    1. when(apiService.discover(SORT_BY_POPULARITY, PAGE, API_KEY)).thenReturn(Observable.just(mDiscoverMoviesResponse)); 

    // when getPopularMovies is invoked 
    2. mRemoteRepository.getPopularMovies(1).subscribeWith(mMovieListTestSubscriber); 

    // then, verify that the api request is made and returns the expected response 
    3. verify(apiService).discover(SORT_BY_POPULARITY, PAGE, API_KEY); 
    4. mMovieListTestSubscriber.assertValue(mMovieList); 
} 

私はそれを実行しようとしたが、私はオプション1オプション2は、あまりにも行い、常に実行気づきました。しかし、オプション3がオプション2の情報と一致しない場合、 は、それらが同じではないというエラーを投げます。つまり、オプション3はオプション2を確認します。私が間違っているか、何か修正が必要な場合は、 を教えてください。だから、私はこのような何かを書いた:

@Test 
public void testBadHashException() throws Exception { 

    1. mRemoteRepository.getPopularMovies(1, FAKE_API_KEY).subscribeWith(mMovieListTestSubscriber); 

    2. mMovieListTestSubscriber.assertNoValues(); 
    3. mMovieListTestSubscriber.assertError(HttpException.class); 
} 

これは私が気づいたものです:

private List<Movie> mMovieList; 
private DiscoverMoviesResponse mDiscoverMoviesResponse; 

private MoviesRepository mRemoteRepository; 

private TestObserver<List<Movie>> mMovieListTestSubscriber; 
private TestObserver<Movie> mMovieTestSubscriber; 

@Mock 
MovieApiService apiService; 

上記のものを、先頭で宣言し、このようなMockito @Before @annotationによって初期化された:

@Before 
public void setup() { 
    MockitoAnnotations.initMocks(this); 

    mRemoteRepository = new MoviesRemoteRepository(apiService); 

    mMovieTestSubscriber = new TestObserver<>(); 
    mMovieListTestSubscriber = new TestObserver<>(); 

    mMovieList = TestDataGenerator.generateMovieList(10); 
    mDiscoverMoviesResponse = TestDataGenerator.generateDiscoverMoviesResponse(mMovieList); 
} 

注:TestDataGeneratorは、データを生成するヘルパークラスです。そこで行われたように、彼はMovieListを取得し、主な応答の本体である別のものを得ました。

APIService:改造サービスクラス。 MoviesRepository:サービスクラスのObservableを操作するヘルパークラス。 ViewModelによって使用されます。

2番目のテストは、私にjava.lang.RuntimeException: No mock defined for invocationを与え続けます。私はまだそれを理解していないようです。 Observable Retrofit Request Errorsをどのようにテストすればよいのですか?

モックデータがない場合は、これが実行されるとモックデータが生成されます。それとも別のことを嘲笑されることになっていますか?

mMovieList = TestDataGenerator.generateMovieList(10); mDiscoverMoviesResponse = TestDataGenerator.generateDiscoverMoviesResponse(mMovieList);

私の観察の詳細を:

私はMockitoを通じて行っていたと私は彼がしたので通過した最初のテストを実行していた、気づい:

1. when(apiService.discover(SORT_BY_POPULARITY, PAGE, API_KEY)).thenReturn(Observable.just(mDiscoverMoviesResponse));

ので、 2番目の関数のエラーがjava.lang.RuntimeException: No mock defined for invocationと表示されている場合、クラス内のメソッド は0を使用して偽装できますは大丈夫です。私はこのように見えるために私testBadHashExceptionを変更:代わりにそれの

@Test 
public void testBadHashException() throws Exception { 

    0. when(apiService.discover(SORT_BY_POPULARITY, PAGE, API_KEY)).thenReturn(Observable.just(mDiscoverMoviesResponse)); 

    1. mRemoteRepository.getPopularMovies(1, FAKE_API_KEY).subscribeWith(mMovieListTestSubscriber); 

    2. mMovieListTestSubscriber.assertNoValues(); 
    3. mMovieListTestSubscriber.assertError(HttpException.class); 
} 

が例外を投げ、それが成功を投げました。

私は、エラーテストを書き直し:

@Test 
public void getPopularMoviesThrowsError() { 
    when(mMoviesRepository.getPopularMovies(PAGE)).thenReturn(Observable.<List<Movie>>error(new TimeoutException())); 

    // request movies 
    mMoviesViewModel.discoverMovies(true); 

    verify(mMoviesRepository).getPopularMovies(PAGE); 

    // check that empty view is hidden 
    assertFalse(mMoviesViewModel.emptyViewShowing.get()); 

    // check that loading view is hidden 
    assertFalse(mMoviesViewModel.moviesLoading.get()); 

    // check that error view is showing 
    assertTrue(mMoviesViewModel.errorViewShowing.get()); 
} 

コンパイルエラーがここにあります:when(mMoviesRepository.getPopularMovies(PAGE)).thenReturn(Observable.<List<Movie>>error(new TimeoutException()));

それはここの方法を解決することはできません:Androidの中でテストを書くObservable.<List<Movie>>error(new TimeoutException())

には、JavaScriptに比べて本当に奇妙に見えます。私がどのようにユニットテストを書くかを理解したり学ぶことができる方法についての助けがあれば幸いです。私はちょうど MVVMパターンを採用し、私はそれを使ってテストを書くことを試みています。ありがとう。

+2

getPopularMovies(1、FAKE_API_KEY)を呼び出すと、apiServiceのどのメソッドが呼び出されますか?あなたはmockitoを使ってこのメソッドを嘲笑しましたか? –

+0

@LeandroBorgesFerreira私の質問が更新されました –

+0

何が成功していますか?テストまたはgetPopularMovies Observable?私はあなたが何をしようとしているのかわかりません...例外をスローするObservableを返すためにapiServiceが必要ですか? Observableを変更して、必要な例外をスローする必要があります –

答えて

0

あなたが観察可能にエラーを送信する必要がある場合は、このようにそれを作成することができます:あなたは

mMovieListTestSubscriber.assertErrorを呼び出すことができますので、あなたがエラーを返すこと観察可能になります

when(mMoviesRepository.getPopularMovies(PAGE)).thenReturn( 
    Observable.create(new Observable.OnSubscribe<SomeClass>() { 
     @Override public void call(Subscriber<SomeCladd> subscriber) { 
      subscriber.onError(new Exception("some message!")); 
     } 
     })); 

この道を

Observableを作成するためにObservable.justを使用しているという問題があります。そのため、onErrorメソッドは決してonNextだけ呼び出されることはありません。

関連する問題