2017-11-22 15 views
0

私はcold observableを購読するコードの一部をテストしようとしています。私の問題は、単体テストが、結果をアサートする前に内部観測可能なコールが終了するのを待っているわけではないから、テストが失敗するということです。ここでユニットテストでは、結果をアサートする前にRxJava2 Observableが終了するのを待つ方法

は、私がテストしたいコードは次のとおりです。

public class UserManager { 

    private UserRepository userRepository; 
    private PublishSubject<List<User>> usersSubject = PublishSubject.create(); 

    public UserManager(UserRepository userRepository) { 
     this.userRepository = userRepository; 
    } 

    public Observable<List<User>> users() { 
     return usersSubject; 
    } 

    public void onUserIdsReceived(List<String> userIds) { 
     userRepository.getUsersInfo(userIds) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(new SingleObserver<List<User>>() { 
       @Override 
        public void onSubscribe(@NonNull Disposable d) {} 

        @Override 
        public void onSuccess(@NonNull List<User> users) { 
         usersSubject.onNext(users); 
        } 

        @Override 
        public void onError(Throwable e) {} 
       } 
    } 
} 

そしてここでは、私のテストです:

@RunWith(MockitoJUnitRunner::class) 
class UserManagerTest { 

private val userRepository = mock(UserRepository::class.java) 

companion object { 
    @BeforeClass 
    @JvmStatic 
    fun setup() { 
     RxJavaPlugins.setIoSchedulerHandler({ _ -> TestScheduler() }) 
     RxJavaPlugins.setSingleSchedulerHandler({ _ -> TestScheduler() }) 
     RxJavaPlugins.setNewThreadSchedulerHandler({ _ -> TestScheduler() }) 
     RxJavaPlugins.setComputationSchedulerHandler({ _ -> TestScheduler() }) 
     RxAndroidPlugins.setInitMainThreadSchedulerHandler({ _ -> TestScheduler() }) 
     RxAndroidPlugins.setMainThreadSchedulerHandler({ _ -> TestScheduler() }) 
    } 
} 

@Test 
fun testReceivedUserIdResultsInPushedUser() { 
    // Given 
    val usersIds = mutableListOf<String>() 
    usersIds.add("id1") 
    val usersDetails = mutableListOf<User>() 
    usersDetails.add(User.testUser()) 
    given(userRepository.getUsersInfo(usersIds)).willReturn(Single.just(usersDetails)) 

    val userManager = UserManager(userRepository) 
    val testObserver = TestObserver<List<User>>() 
    userManager.users().subscribeWith(testObserver) 

    // When 
    userManager.onUsersIdsReceived(usersIds) 

    // Then 
    testObserver.assertNoErrors() 
    testObserver.assertNotComplete() 
    testObserver.assertValueCount(1) 
    testObserver.assertValue({ detectedUsers: List<DetectedUser> -> 
     // My test 
    }) 
} 

私testObserverは、任意のイベントを受信して​​いないので、私のテストが失敗し、最も論理的な理由がありますUserRepository.getUsersInfo(userIds)の呼び出しが終了するのを待つことはありません。私がUserRepositoryを嘲笑してTestSchedulerを使用したとしても、テストは終了します。 内部Observable呼び出しが終了するのを待つ方法があるので、コードをテスト可能にしていますか?

+0

あなたは 'TestObserver#awaitCount()'を使用することをお勧めします – rciovati

答えて

1

私はこのようにTestSchedulerの代わりにtrampolineを使用しています。これは同期的に実行されます。

// override Schedulers.io() 
RxJavaPlugins.setIoSchedulerHandler(schedulerCallable -> Schedulers.trampoline()); 
// override AndroidSchedulers.mainThread() 
RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerCallable -> Schedulers.trampoline()); 

はまた、私は私はそれでいくつかの問題を抱えていたと思います RxAndroidPlugins.setMainThreadSchedulerHandler({ _ -> TestScheduler() }) を削除することを検討します。

+0

Shedulers.transpoline()はトリックをしました、ありがとう! – MickaelG

関連する問題