Mockito Wanted, но не вызывается

Я новичок в написании тестов и использовании Mockito. Я прочитал аналогичные темы здесь, в Stackoverflow, и сделал предлагаемые изменения, убедившись, что рассматриваемые классы / интерфейсы / методы открыты.

Я попытался следовать этому

Издевательствование зависимых от конструктора зависимостей

Это тест, к которому я придумал

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). Я считаю, что методы переопределения открыты по природе в котлине.

  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> } 

Вся помощь приветствуется.

Если вы используете простой jUnit, ваш AndroidSchedulers.mainThread() имеет значение null. Вот почему 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() регистрацию планировщиков в tearDown() следующим образом:

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