Spek + Retrofit API тестовый сбой - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь проверить Retrofit API с помощью Spek

Выдает исключение nullPointerException для в {...} блоке

Связанная трассировка стека: https://pastebin.com/gy6dLtGg

Вот мой тестовый класс

@RunWith(JUnitPlatform::class)
class AccountCheckViewModelTest : Spek({

    include(RxSchedulersOverrideRule)

    val httpException = mock<HttpException> {
        on { code() }.thenReturn(400)
    }

    given(" account check view model") {
        var accountCheckRequest = mock<CheckExistingAccountRequest>()
        var accountCheckResponse = mock<CheckExistingAccountResponse>()
        var webService = mock<IAPICalls>()

        val accountCheckViewModel = spy(VMAccountCheck(webService))

        beforeEachTest {
            accountCheckRequest = mock<CheckExistingAccountRequest>() {
                on { email }.thenReturn("foo@mail")
            }

            accountCheckResponse = mock<CheckExistingAccountResponse>() {
                on { firstName }.thenReturn("foo")
                on { email }.thenReturn("foo@mail")
            }

            webService = mock<IAPICalls> {
                on { checkExistingAccount(accountCheckRequest) }.thenReturn(Flowable.just(accountCheckResponse))
            }
         }
        on("api success") {
            accountCheckViewModel.checkIfAccountExists(request = accountCheckRequest)

            it("should call live data with first name as foo") {
               verify(accountCheckViewModel, times(1)).updateLiveData(accountCheckResponse.firstName, accountCheckResponse.email, null)
            }
        }
    }
}

Вот мой класс RxSchedulersOverrideSpek

 class RxSchedulersOverrideSpek : Spek({

    beforeGroup {
        RxJavaPlugins.onIoScheduler(Schedulers.trampoline())
        RxJavaPlugins.onComputationScheduler(Schedulers.trampoline())
        RxJavaPlugins.onNewThreadScheduler(Schedulers.trampoline())
    }
})

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Если вы используете RxJava2 с RxAndroid , вы должны переопределить планировщик RxAndroid с Schedulers.trampoline(). Таким образом, все задания, которые подписываются на trampoline (), ставятся в очередь и выполняются по очереди в одном потоке.

RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }

Ваш RxSchedulersOverrideSpek.kt должен выглядеть так:

object RxSchedulersOverrideSpek : Spek({

    beforeGroup {
        RxJavaPlugins.onIoScheduler(Schedulers.trampoline())
        RxJavaPlugins.onComputationScheduler(Schedulers.trampoline())
        RxJavaPlugins.onNewThreadScheduler(Schedulers.trampoline())
        RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
    }

    afterGroup {
        RxJavaPlugins.reset()
        RxAndroidPlugins.reset()
    }
})
0 голосов
/ 27 апреля 2018

Вы должны использовать memoized для правильной настройки тестовых значений. Проблема в том, что accountCheckViewModel был инициализирован в фазе обнаружения Spek, макет webService, который был передан accountCheckViewModel, был значением в тот момент (который вы не высмеивали ни одним из его методов). beforeEachTest запускается на этапе выполнения, вы переназначили webService здесь для правильного макета, но accountCheckViewModel все еще содержит предыдущее значение.

given(" account check view model") {
  val accountCheckRequest by memoized {
    mock<CheckExistingAccountRequest>() {
      on { email }.thenReturn("foo@mail")
    }
  }
  val accountCheckResponse by memoized {
    mock<CheckExistingAccountResponse>() {
      on { firstName }.thenReturn("foo")
      on { email }.thenReturn("foo@mail")
    }
  }
  val webService by memoized {
    mock<IAPICalls> {
      on { checkExistingAccount(accountCheckRequest) }.thenReturn(Flowable.just(accountCheckResponse))
    }
  }

  val accountCheckViewModel by memoized {
    spy(VMAccountCheck(webService))
  }

  on("api success") {
    accountCheckViewModel.checkIfAccountExists(request = accountCheckRequest)

    it("should call live data with first name as foo") {
      verify(accountCheckViewModel, times(1)).updateLiveData(accountCheckResponse.firstName, accountCheckResponse.email, null)
    }
  }
}
...