尝试在Kotlin Android应用中测试ViewModel注入时出现Koin NullPointerException

时间:2019-03-06 17:38:53

标签: android unit-testing junit kotlin koin

我正在尝试测试ViewModel是否已成功将存储库注入其中。但是,我得到了NPE。该代码对于实际的应用程序工作正常,但不适用于测试。我认为找不到正确的ViewModel。

这是代码:

    package com.waynecovell.kotlinbasics

import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModel
import com.waynecovell.kotlinbasics.data.Workout
import com.waynecovell.kotlinbasics.data.WorkoutRepository
import com.waynecovell.kotlinbasics.data.WorkoutRepositoryTestImpl
import com.waynecovell.kotlinbasics.ui.WorkoutViewModel
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.koin.android.viewmodel.ext.koin.viewModel
import org.koin.dsl.module.Module
import org.koin.dsl.module.module
import org.koin.standalone.StandAloneContext.startKoin
import org.koin.standalone.StandAloneContext.stopKoin
import org.koin.standalone.inject
import org.koin.test.KoinTest
import org.koin.test.declareMock
import org.mockito.Mock
import org.mockito.MockitoAnnotations

class WorkoutKoinTest : KoinTest {

    val viewModel: WorkoutViewModel by inject<WorkoutViewModel>()
    val repository by inject<WorkoutRepository>()

    @Mock
    lateinit var uiData: Observer<List<Workout>>

    val workoutModule : Module = module {
        viewModel { WorkoutViewModel(get()) }
        single<WorkoutRepository> { WorkoutRepositoryTestImpl() }
    }

    @Before
    fun before() {
        MockitoAnnotations.initMocks(this)
        startKoin(
            listOf(workoutModule)
        )
        declareMock<WorkoutViewModel>()
        //declareMock<WorkoutRepository>()
    }

    @After
    fun after() {
        stopKoin()
    }


    @Test
    fun testKoinRepo() {
        //data
        val workouts = repository.getWorkouts()

        //observe
        viewModel.getWorkouts().observeForever(uiData)

        //has data
        Assert.assertNotNull(viewModel.workoutData.value)

    }
}

科因日志:

2019-03-06 17:33:21:771 (KOIN)::[i] [PrintLogger] display debug = false
2019-03-06 17:33:21:803 (KOIN)::[i] [definition] declare Factory [name='WorkoutViewModel',class='com.waynecovell.kotlinbasics.ui.WorkoutViewModel']
2019-03-06 17:33:21:803 (KOIN)::[i] [definition] declare Single [name='WorkoutRepository',class='com.waynecovell.kotlinbasics.data.WorkoutRepository']
2019-03-06 17:33:21:803 (KOIN)::[i] [modules] loaded 2 definitions
2019-03-06 17:33:21:803 (KOIN)::[i] [modules] loaded in 5.670703 ms
2019-03-06 17:33:21:803 (KOIN)::[i] [Koin] started in 28.810215 ms
2019-03-06 17:33:21:804 (KOIN)::[i] [mock] declare mock for class com.waynecovell.kotlinbasics.ui.WorkoutViewModel (Kotlin reflection is not available)
2019-03-06 17:33:21:804 (KOIN)::[i] [definition] override Factory [name='WorkoutViewModel',class='com.waynecovell.kotlinbasics.ui.WorkoutViewModel']
2019-03-06 17:33:21:809 (KOIN)::[i] +-- 'com.waynecovell.kotlinbasics.ui.WorkoutViewModel'
2019-03-06 17:33:21:870 (KOIN)::[i] \-- (*) Created
2019-03-06 17:33:21:873 (KOIN)::[i] +-- 'com.waynecovell.kotlinbasics.data.WorkoutRepository'
2019-03-06 17:33:21:876 (KOIN)::[i] \-- (*) Created
2019-03-06 17:33:21:876 (KOIN)::[i] +-- 'com.waynecovell.kotlinbasics.ui.WorkoutViewModel'
2019-03-06 17:33:21:877 (KOIN)::[i] \-- (*) Created
2019-03-06 17:33:21:898 (KOIN)::[i] [Koin] close context

NPE:

java.lang.NullPointerException
    at com.waynecovell.kotlinbasics.WorkoutKoinTest.testKoinRepo(WorkoutKoinTest.kt:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

0 个答案:

没有答案