(RxJava2) Single.blockingGet () не работает в модульном тесте

Я создал модульный тест для метода интерактора, возвращающего Rx Single. Single должен возвращать bean-компонент пользователя асинхронно. Я попытался вызвать blockingGet () для Single, но компонент не возвращается, поскольку тест работает бесконечно. Я проверил точки останова и увидел, что компонент был создан, но не вернулся. Также я попытался вызвать test (). Values ​​(). Get (0) для Single, но он не содержал bean. Точки останова не вызывались.

Могу понять, в чем проблема. Мне нужна помощь, чтобы решить эту проблему.

Метод в интеракторе.

    public Single<UserBean> verifyUser() {
    String jwt = getJWTToken();
    if (TextUtils.isEmpty(jwt)) {
        return Single.error(new EmptyJWTException());
    }
    if (!checkConnectionInfo()) {
        return Single.error(new NotNetworkConnectedException());
    }
    return Single.create((SingleOnSubscribe<UserBean>) emitter -> {
        UserBean resultBean = mAuthenticationRepository.verifyUserByJwt(jwt);
        if (resultBean != null && !TextUtils.isEmpty(resultBean.getId())) {
            emitter.onSuccess(resultBean);
        } else {
            emitter.onError(new RequestToServerException());
        }
    })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

Модульный тест.

@RunWith(MockitoJUnitRunner.class)
public class AuthenticationInteractorTest {

@Mock
private Application mApplication;
@Mock
private IAuthenticationRepository mAuthenticationRepository;
@Mock
private SharedPreferences mSharedPreferences;
@Mock
private ConnectivityManager mConnectivityManager;
@Mock
private NetworkInfo mNetworkInfo;
private AuthenticationInteractor mInteractor;

@Before
public void setUp() {
    mInteractor = new AuthenticationInteractor(mAuthenticationRepository, mApplication);
}

@Test
public void verifyUserTest() {
    String jwt = "jwt";
    UserBean userBean = createUserBean();
    when(mApplication.getSharedPreferences(AuthenticationInteractor.SHARED_PREFS, Context.MODE_PRIVATE)).thenReturn(mSharedPreferences);
    when(mSharedPreferences.getString(AuthenticationInteractor.TOKEN_KEY, null)).thenReturn(jwt);
    when((ConnectivityManager) mApplication.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mConnectivityManager);
    when(mConnectivityManager.getActiveNetworkInfo()).thenReturn(mNetworkInfo);
    when(mNetworkInfo.isConnected()).thenReturn(true);
    when(mAuthenticationRepository.verifyUserByJwt(jwt)).thenReturn(userBean);
    UserBean bean = mInteractor.verifyUser().blockingGet();
    assertEquals(userBean, bean);
}

private UserBean createUserBean() {
    UserBean userBean = new UserBean();
    userBean.setMetaId("1539762652616:940c29e6d716:15:jmt4z02l:11182");
    userBean.setJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1hZ2F6b240aWtAeWFuZGV4LnJ1IiwiY3MiOiI1OWEwNDA2MTgzNDAwMDAwIiwiaWF0IjoxNTM5NzYyNjUyLCJhdWQiOiIqLmxvY2FsaG9zdCIsImlzcyI6Im1zLXVzZXJzIn0.2AcuLZjR_-GyWAFen7JczJ5-W37zQWGbnRRErGLqDEY");
    userBean.setId("[email protected]");
    userBean.setType("user");
    userBean.setUserName("[email protected]");
    userBean.setCreated(1535970916310L);
    userBean.setLatestResult("1539676474685");
    userBean.setOnDiet("No");
    return userBean;
}

}

0
0
841
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, вы не отменяете используемые планировщики. Без этого вы почти наверняка получите следующую ошибку при попытке подписаться с помощью AndroidSchedulers.mainThread.

Method getMainLooper in android.os.Looper not mocked

Чтобы преодолеть это, вы можете создать TestRule, который позволяет вам указывать планировщики для вашего теста, например следующее приведет к сбросу Schedulers.io и AndroidSchedulers.mainThread с помощью Schedulers.trampoline.

public class RxSchedulersRule implements TestRule {
    @Override
    public Statement apply(final Statement base, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                RxAndroidPlugins.reset();
                RxJavaPlugins.reset();

                RxAndroidPlugins.setInitMainThreadSchedulerHandler(s -> Schedulers.trampoline());
                RxJavaPlugins.setIoSchedulerHandler(s -> Schedulers.trampoline());

                try {
                    base.evaluate();
                } finally {
                    RxAndroidPlugins.reset();
                    RxJavaPlugins.reset();
                }
            }
        };
    }
}

Чтобы использовать в своем тесте, вам нужно будет объявить правило

@Rule public final RxSchedulersRule schedulersRule = new RxSchedulersRule();

Другие вопросы по теме