UntTest - 在UseCase对象中模拟RxJava对象

时间:2016-04-26 19:13:45

标签: android unit-testing mockito rx-java

我想测试UseCase对象,在这种特定情况下有一个LoginUseCase,如下所示:

public class LoginUseCase implements RxUseCase<AuthResponse, AuthCredentials> {

    ApiManager mApiManager;

    public LoginUseCase(ApiManager apiManager) {
        mApiManager =apiManager;
    }

    @Override
    public Observable<AuthResponse> execute(final AuthCredentials authCredentials) {
        return Observable.just(1)
                .delay(750, TimeUnit.MILLISECONDS)
                .flatMap(l -> mApiManager.login(authCredentials.getLogin(), authCredentials.getPassword()));
    }
}

我写了简单的测试:

@RunWith(MockitoJUnitRunner.class)
public class LoginUseCaseTest {

    private LoginUseCase mLoginUseCase;
    @Mock ApiManager mApiManager;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mLoginUseCase = new LoginUseCase(mApiManager);
    }


    @Test
    public void testShouldThrowsError() throws Exception {
        TestSubscriber<AuthResponse> testSubscriber = new TestSubscriber<>();
        doReturn(Observable.error(new Throwable())).when(mApiManager).login("", "");
        mLoginUseCase
            .execute(new AuthCredentials("", ""))
            .subscribe(testSubscriber);
        testSubscriber.assertNoErrors();

    }
}

但是这个测试总是通过,我不知道在这种情况下如何模拟错误可观察。

编辑:我已经根据SkinnyJ对testShouldThrowsError()进行了测试,但是测试仍然通过,任何过度消息?

1 个答案:

答案 0 :(得分:1)

在断言之前,您需要在测试用户上调用awaitTerminalEvent()。 因为现在,您计划在Schedulers.computation上运行延迟,并且您的测试方法在完成observable之前成功完成。

替代方法是将调度程序作为参数传递给execute方法,或将调度程序存储在用例中。这样,在测试期间,您可以传递Schedulers.immediate(),并且您的测试将在当前线程上运行(这将阻止执行指定的延迟)。

最后一种方法是在observable上调用toBlocking(),但我认为传递调度程序是首选。并且无法将此运算符添加到当前的observable中。