J'ai essayé d'obtenir une réponse de RxJava2 dans le test unitaire, j'ai trouvé un exemple de comment le faire, mais je ne peux pas voir et répondre, pouvez-vous m'aider? Merci. Le code lui-même fonctionnait depuis longtemps, sans problème, et lorsque les tests étaient nécessaires j'ai rencontré un problème, des exemples similaires sont plus ou moins les mêmes, mais partout c'est fait de cette façon, mais cela ne fonctionne pas pour moi.

Là mon code du présentateur:

  fun register(
    email: String,
    password: String,
    termsEnabled: Boolean,
    dayOfBirth: Int,
    monthOfBirth: Int,
    yearOfBirth: Int,
    formattedBirthDate: String,
    state: String?
) {
    addDisposable(
        registerUseCase.run(
            RegisterUseCase.RegisterRequest(
                email,
                password,
                termsEnabled,
                formattedBirthDate,
                state ?: ""
            )
        )
            .observeOn(mainThreadScheduler)
            .subscribeOn(backgroundScheduler)
            .subscribe(
                { 
                  getView?.showEmptyPassword()
                }, {
                 getView?.showEmptyPassword()
                    }
            )
    )
}

Et test:

@Before
fun setUp() {
    RxAndroidPlugins.setInitMainThreadSchedulerHandler { 
    Schedulers.trampoline() }
    MockitoAnnotations.initMocks(this)

    
    presenter = CreateAccountPresenter(
        mainThreadScheduler,
        backgroundScheduler,
        registerUseCase,
        getUserDataUseCase,
        getStatesUseCase,
        regexUtils,
        router,
        resourceUtils,
        deviceSharedPreferences
    )
    presenter.setView(view)
}


@Test
fun testRegister() {

    given(registerUseCase.run(RegisterUseCase.RegisterRequest(
        EMAIL, PASSWORD, true,
                FORMATTED_BIRTHDAY, STATE))
    ).willReturn(Single.just(RegisterResponse(false, "ok", "id")))

    presenter.register(
        EMAIL,
        PASSWORD,
        true,
        1,
        1,
        1,
        FORMATTED_BIRTHDAY,
        STATE)

    verify(view).showEmptyPassword()
}

Mais le problème est :

Wanted but not invoked:
view.showEmptyPassword();
-> at 
com.unikrn.esports.umode.CreateAccountPresenterTest.testRegister(CreateAccountPresenterTest.kt:179)
Actually, there were zero interactions with this mock.
1
Azarnoy 16 sept. 2020 à 14:14

1 réponse

Meilleure réponse

Le problème est que vous effectuez des calculs dans un thread d'arrière-plan et, même en étant moqué, il n'a pas assez de temps pour terminer avant l'invocation verify

Puisque vous injectez déjà les planificateurs pour vos opérations, spécifiez que les deux sont trampoline afin que tout s'exécute dans le même thread

@Before
fun setUp() {
    presenter = CreateAccountPresenter(
        Schedulers.trampoline(),
        Schedulers.trampoline(),
        ...
    )
}

Dans le pire des cas, vous pouvez ajouter un élément bloquant (comme un Semaphore) qui bloque l'exécution du test et vous le relâchez dans l'une de vos méthodes view (que vous devrez stub)

Conformément à la documentation, Schedulers.trampoline () planifie toutes les tâches dans le thread actuel afin que tout soit bloqué. Si vous souhaitez utiliser directement certains planificateurs comme Schedulers.io(), vous devrez les remplacer de la même manière que vous le faites maintenant avec

RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() } // Override MainThreadScheduler

Notez que l'extrait précédent n'est qu'un exemple et vous devrez l'adapter

1
Pelocho 16 sept. 2020 à 13:55