Ошибка модульного тестирования Kotlin Coroutine: исключение в потоке "main @ coroutine # 1 @ coroutine # 2" java.lang.NullPointerException - PullRequest
0 голосов
/ 05 мая 2018

Я пытаюсь провести модульное тестирование презентера, который я сделал с сопрограммами Kotlin, и это также мой первый раз, используя Mockito

Всякий раз, когда я пытаюсь запустить модульный тест, я получаю следующую ошибку, когда в первый раз он пытается что-то сделать с моим видом, находясь в сопрограмме

Exception in thread "main @coroutine#1 @coroutine#2" java.lang.NullPointerException
    at .signin.SignInPresenter$subscribe$1.doResume(SignInPresenter.kt:45)
    at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:54)
    at kotlinx.coroutines.experimental.DispatchedKt.resumeCancellable(Dispatched.kt:208)
    at kotlinx.coroutines.experimental.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:35)
    at kotlinx.coroutines.experimental.CoroutineStart.invoke(CoroutineStart.kt:111)
    at kotlinx.coroutines.experimental.AbstractCoroutine.start(AbstractCoroutine.kt:161)
    at kotlinx.coroutines.experimental.BuildersKt.launch(Builders.kt:68)
    at kotlinx.coroutines.experimental.BuildersKt.launch$default(Builders.kt:61)
    at .signin.SignInPresenter.subscribe(SignInPresenter.kt:42)

Это релевантная часть моего докладчика, строка, на которую ссылается ошибка: view.showSigninPanel

class SignInPresenter(
    private val view: SignInContract.View,
    private val userRepo: ParseAuthController,
    private val contextPool: CoroutineContextProvider
) : SignInContract.Presenter {

    private val coroutineJobs: MutableList<Job> = mutableListOf()

    override fun subscribe() {
        view.loadBackgroundImage()
        view.setUpSignInPanel()
        view.setUpKeyboardListener()

        coroutineJobs.add(launch(contextPool.Main) {
            if (!userRepo.isAuthenticated()) {
                view.showSignInPanel()
                subscribeToLoginValidation()
                subscribeToPaswordEmailValidation()
            } else {
                view.launchMainActivity()
            }
        })
    }

Звонок на userRepo.isAuthenticated() является приостановленным звонком

Я передаю тестовый сопрограммный контекст своему докладчику в соответствии с этой статьей

https://android.jlelse.eu/mastering-coroutines-android-unit-tests-8bc0d082bf15

class TestContextProvider : CoroutineContextProvider() {
    override val Main: CoroutineContext = Unconfined
    override val IO: CoroutineContext = Unconfined
}

Это мой тестовый модуль

class SignInPresenterTest {

    private lateinit var view: SignInContract.View
    private lateinit var presenter: SignInPresenter
    private lateinit var parseAuthController: ParseAuthController

    @Before
    fun setUp() {
        view = mock(SignInContract.View::class.java)

        parseAuthController = mock(ParseAuthController::class.java)

        presenter = SignInPresenter(
            view,
            parseAuthController,
            TestContextProvider()
        )
    }

    @After
    fun tearDown() {
        presenter.dispose()
    }

    @Test
    fun subscribeNotAuthenticatedShowSignInPanel() {
        runBlocking {
            val expectedResult = false
            `when`(parseAuthController.isAuthenticated()).thenReturn(expectedResult)

            presenter.subscribe()
        }

        verify(view).showSignInPanel()
    }
}

ОБНОВЛЕНИЕ: я проводил некоторые дополнительные тесты, и похоже, что если я удалю вызов приостановки в моем докладчике if (!userRepo.isAuthenticated()), он не завершится сбоем, и я смогу проверить, что-то запускалось с Mockito, но это не так. не реальное решение ... но что-то с этим приостановлением вызова вызывает проблемы?

1 Ответ

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

Проблема решена!

Приведенный выше код на самом деле правильный. У меня была неправильная зависимость от Мокито.

Я копировал некоторые зависимости из репозитория сотрудников, и они использовали эту библиотеку, которая предоставляет некоторые специфические функции Kotlin

https://github.com/nhaarman/mockito-kotlin

Либо что-то есть, что нарушает поддержку сопрограмм, или, может быть, существуют другие требования, чтобы это работало?

Обновление до последней версии зависимостей Mockito.

...