2017-11-22 1 views
0

콜드 관측 가능 이벤트에 가입 한 코드 일부를 테스트하려고합니다. 내 문제는 단위 테스트가 내부 관찰 가능 호출이 결과를 주장하기 전에 끝나기를 기다리지 않기 때문에 테스트가 실패한다는 것입니다. 여기 유닛 테스트에서 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

관련 문제