2016-11-18 23 views
0

我是新来编写测试和使用Mockito。 我已经阅读了Stackoverflow上的类似主题,并提出了建议的更改,确保所考虑的类/接口/方法处于打开状态。Mockito通缉但未被调用

I tried to follow this

惩戒构造函数注入依赖

这是我想出了迄今为止

class RegistrationPresenterTest { 
@Test 
fun testRegisterSuccess() { 
    val mockService = mock<IHerokuInteractor>() 
    val mockLocal = mock<ILocalStorageInteractor>() 
    val mockView = mock<RegisterView>() 
    val mockRegistrationResponse = HerokuRegisterResponse("hash") 
    val mockPair = ImeiPair("imei","hash") 
    val presenter = RegisterPresenterImpl(mockLocal,mockService) 

    whenever(mockService.register(any())).thenReturn(Observable.just(mockRegistrationResponse)) 
    whenever(mockLocal.clearPreferences()).thenReturn(Observable.just(true)) 
    whenever(mockLocal.putImeiPair(any())).thenReturn(Observable.just(true)) 
    //whenever(presenter.writeImeiPairLocally(any())) How do I specify parameters since it uses a parameter from the register method? 

    presenter.bindView(mockView) 
    presenter.register("imei","male") 

    verify(mockService, times(1)).register(any()) 
    verify(mockLocal,times(1)).clearPreferences() 
    verify(mockLocal,times(1)).putImeiPair(any()) 
    verify(mockView,times(1)).moveToMain() 
} 

,但我不断收到响应

Wanted but not invoked: 
registerPresenterImpl.writeImeiPairLocally(
<any com.company.appname.model.ImeiPair> 
); 

Actually, there were zero interactions with this mock. 
测试

即使我在测试中没有提到该方法,我也得到了这个答案。 这是我的演示者注册方法。我已经改变了涉及打开(kotlin)的类/接口&。我相信覆盖方法在kotlin中本质上是开放的。

open class RegisterPresenterImpl @Inject constructor(val localStorage : ILocalStorageInteractor, var herokuService : IHerokuInteractor) 

override fun register(imei : String, gender : String){ 
    subscription = herokuService.register(RegisterObject(imei,gender)).subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()).subscribe(
      { 
       registrationResult -> 
       Log.d(TAG,"${registrationResult}") 
       if(registrationResult.imei_hash != null){ 
        writeImeiPairLocally(ImeiPair(imei,registrationResult.imei_hash)) 
       } 
       else{ 
        Log.e(TAG,"User already exists") 
       } 
      }, 
      { 
       errorResponse -> Log.e(TAG,"Could not register user ${errorResponse.message}") 
      } 
    ) 
    addSubscription(subscription) 
} 

,同样的

open fun writeImeiPairLocally(pair : ImeiPair){ 
    subscription = localStorage.clearPreferences().flatMap { 
     cleared -> localStorage.putImeiPair(pair)}.subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()).subscribe(
      { 

       booleanResult -> view?.moveToMain() 
      }, 
      { 
       errorResponse -> Log.e(TAG,"Could not write ImeiPair to SharedPreferences ${errorResponse.message}") 
      } 
    ) 
    addSubscription(subscription) 

} 

这里是所有的帮助表示赞赏接口

open interface ILocalStorageInteractor : ILocalStorage{ 
    fun getImeiPair() : Observable<ImeiPair> 
    fun putImeiPair(pair: ImeiPair) : Observable<Boolean> 
} 

open interface ILocalStorage { 
    fun clearPreferences() : Observable<Boolean> 
} 

回答

1

如果您使用的是纯jUnit,那么您的AndroidSchedulers.mainThread()为空。这就是为什么onNext没有被调用。

你需要重写调度程序在setUp()法:

RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() { 
     @Override 
     public Scheduler getMainThreadScheduler() { 
      return Schedulers.immediate(); // or .test() 
     } 
    }); 

为了避免测试的并发性,我建议重写Schedulers.io()这样的:

RxJavaHooks.setOnIOScheduler(scheduler1 -> Schedulers.immediate()); 

如果你要使用TestScheduler,不要忘了拨打TestScheduler.triggerActions()方法。

也不要忘记注销调度程序在tearDown()这样的:

RxJavaHooks.reset(); 
    RxAndroidPlugins.getInstance().reset(); 
    AndroidSchedulers.reset(); 
    Schedulers.reset(); 
+0

谢谢你的答复。我在Before方法setUp()和After tearDown()的最后一个块中添加了前两个代码块,但是我仍然得到相同的响应。这是实施建议更改的正确方法吗?我从来没有做过测试。 – buddhabath

+0

您是否尝试过在'register(imei:String,gender:String)'函数的onNext调用中使用调试器? –

+0

移动测试之后(它是在工具测试中),现在我得到了同样的错误,但对于clearPreferences(),请检查我原始帖子的底部。起初它抱怨在我的Presenter中没有Mocking Log.e() – buddhabath

相关问题