2017-02-21 13 views
1

こんにちは、私はmockitoを使用してAndroidプレゼンターをテストしたいと私は多くの問題を抱えています。RxJavaトラブルテスト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", "[email protected]")) 
       .thenReturn(Single.just(token)); 

     mPresenter.signUp("Username", "password", "[email protected]"); 

     verify(mView).onSuccessSignUp(mUser, null); 
    } 

    @Test 
    public void onSignUpErrorTest() { 
     when(mRepository.signUp("Username", "password", "[email protected]")) 
       .thenReturn(Single.error(new Throwable("Error"))); 

     mPresenter.signUp("Username", "password", "[email protected]"); 

     verify(mView).onErrorSignUp("Error"); 
    } 

} 

と例外:助けを

Wanted but not invoked: 
mView.onSuccessSignUp(
    [email protected], 
    null 
); 
-> at com.andiag.trainingsquad.SignUpPresenterTest.onSuccessSignUpTest(SignUpPresenterTest.java:51) 
Actually, there were zero interactions with this mock. 

Wanted but not invoked: 
mView.onSuccessSignUp(
    [email protected], 
    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) 

おかげでここで私がテストしたいコードがあります。

答えて

4

私はこの問題がバックグラウンドスレッドに関係していると思います(.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は、あなたのテストに適用され、このルールを適用します。

+0

コンストラクタparamとして 'new TestScheduler()'を使用しても同じエラーです。 – iagocanalejas

+1

@iagocanalejas申し訳ありませんが私は明確ではない場合。ユニットテストが実行されている現在のスレッドである 'Schedulers.trampoline()'を試してみてください。 'TestScheduler'では不十分です。 – AndroidEx

+0

これで動作します。あなたに良い答えをありがとう。 – iagocanalejas

関連する問題