RXJAVA在Android中测试主持人的问题



嗨,我想使用Mockito测试Android演示者,并且我遇到了很多麻烦。这是我要测试的代码:

public class SignUpPresenter extends BasePresenter {
    private static final String TAG = SignUpPresenter.class.getSimpleName();
    private final AuthRepository mAuthRepository;
    private final SignUpView mView;
    public SignUpPresenter(@NonNull SignUpView view, @NonNull AuthRepository authRepository) {
        this.mAuthRepository = authRepository;
        this.mView = view;
    }
    public void signUp(@NonNull String username, @NonNull String password, @NonNull String email) {
        mCompositeDisposable.add(mAuthRepository.signUp(username, password, email)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableSingleObserver<TokenWrapper>() {
                    @Override
                    public void onSuccess(TokenWrapper t) {
                        Log.i(TAG, "Signed Up: " + t.getUser().getUsername());
                        mView.onSuccessSignUp(t.getUser(), t.getToken());
                    }
                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "Sign Up: " + e.getMessage());
                        mView.onErrorSignUp(e.getMessage());
                    }
                }));
    }
}

测试代码:

public class SignUpPresenterTest {
    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
    @Mock public SignUpView mView;
    @Mock public AuthRepository mRepository;
    SignUpPresenter mPresenter;
    User mUser = new User();
    @Before
    public void setUp() {
        mPresenter = new SignUpPresenter(mView, mRepository);
    }
    @Test
    public void onSuccessSignUpTest() throws InterruptedException {
        TokenWrapper token = new TokenWrapper(mUser, null);
        when(mRepository.signUp("Username", "password", "asdf@msais.com"))
                .thenReturn(Single.just(token));
        mPresenter.signUp("Username", "password", "asdf@msais.com");
        verify(mView).onSuccessSignUp(mUser, null);
    }
    @Test
    public void onSignUpErrorTest() {
        when(mRepository.signUp("Username", "password", "asdf@msais.com"))
                .thenReturn(Single.error(new Throwable("Error")));
        mPresenter.signUp("Username", "password", "asdf@msais.com");
        verify(mView).onErrorSignUp("Error");
    }
}

和例外:

    Wanted but not invoked:
mView.onSuccessSignUp(
    com.andiag.trainingsquad.models.entities.User@d6e7bab,
    null
);
-> at com.andiag.trainingsquad.SignUpPresenterTest.onSuccessSignUpTest(SignUpPresenterTest.java:51)
Actually, there were zero interactions with this mock.
Wanted but not invoked:
mView.onSuccessSignUp(
    com.andiag.trainingsquad.models.entities.User@d6e7bab,
    null
);
-> at com.andiag.trainingsquad.SignUpPresenterTest.onSuccessSignUpTest(SignUpPresenterTest.java:51)
Actually, there were zero interactions with this mock.
    at com.andiag.trainingsquad.SignUpPresenterTest.onSuccessSignUpTest(SignUpPresenterTest.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.mockito.internal.junit.JUnitRule$1.evaluateSafely(JUnitRule.java:63)
    at org.mockito.internal.junit.JUnitRule$1.evaluate(JUnitRule.java:43)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

感谢您的帮助。

我认为问题在涉及的背景线程中(.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())):在测试的计算之前完成了单元测试。

您应该尝试使用测试规则将线程映射到单元测试中的当前螺纹。这样的东西(我的摘要在Kotlin,但希望总体想法很清楚):

class SchedulersOverrideRule(private val scheduler: Scheduler = Schedulers.trampoline()) : TestRule {
    override fun apply(base: Statement, description: Description?): Statement {
        return object : Statement() {
            override fun evaluate() {
                RxJavaPlugins.setIoSchedulerHandler { scheduler }
                RxJavaPlugins.setComputationSchedulerHandler { scheduler }
                RxJavaPlugins.setNewThreadSchedulerHandler { scheduler }
                RxAndroidPlugins.setInitMainThreadSchedulerHandler { scheduler }
                RxAndroidPlugins.setMainThreadSchedulerHandler { scheduler }
                try {
                    base.evaluate()
                } finally {
                    RxJavaPlugins.reset()
                    RxAndroidPlugins.reset()
                }
            }
        }
    }
}

并按照测试中使用MockitoRule的方式应用此规则。

相关内容

  • 没有找到相关文章

最新更新