5 votes

Kotlin Lazy loading ne fonctionne pas dans un test Junit

Bonjour, j'essaie de charger/injecter des variables dans mon test unitaire en utilisant kotlin koin et cela ne fonctionne pas et j'obtiens une erreur "no class def found" lorsque j'essaie d'utiliser les variables.

Voici mon module :

    val testModules = module {
        single<NetworkControllerContract> {
            Mockito.mock(NetworkControllerContract::class.java)
        }
        single {
            Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext<Context>(),
                    PostDatabase::class.java).allowMainThreadQueries().build()
        }
        single<PostRepositoryContract> { PostRepository(get(), get()) }
//            factory { GetAllDataUseCase(get()) }
        single { create<GetAllDataUseCase>() }
        single { GetCommentCountUseCase(get()) }
        single { GetPostDetailsUseCase(get()) }
        single { GetPostListUseCase(get()) }
    }
}

Voici ma classe de test

class UseCaseUnitTests : KoinTest {

    @get:Rule
    var rule: TestRule = InstantTaskExecutorRule()

    val getAllDataUseCase: GetAllDataUseCase by inject()
    val getCommentCountUseCase: GetCommentCountUseCase by inject()
    val getPostDetailsUseCase: GetPostDetailsUseCase by inject()
    val getPostListUseCase: GetPostListUseCase by inject()
    val networkController: NetworkControllerContract by inject()

    private val testModulesList = listOf(testModules)

    @Before
    fun setup() {
        startKoin(testModulesList)
    }

    @After
    fun cleanUp() {
        stopKoin()
    }

    @Test
    fun testGetAllData() {
        Mockito.`when`(networkController.getUsers()).thenReturn(GlobalScope.async(Dispatchers.Default,
                CoroutineStart.DEFAULT,
                null, { getMockedUser() }))

        Mockito.`when`(networkController.getPosts()).thenReturn(GlobalScope.async(Dispatchers.Default,
                CoroutineStart.DEFAULT,
                null, { getMockedPosts() }))

        Mockito.`when`(networkController.getComments()).thenReturn(GlobalScope.async(Dispatchers.Default,
                CoroutineStart.DEFAULT,
                null, { getMockedComments() }))

        val fetchDataLiveData = getAllDataUseCase.fetchAllData()

        fetchDataLiveData.test()
                .assertHasValue()
                .assertValue(true)
    }

    @Test
    fun testGetCommentCount() {
        getCommentCountUseCase.getCommentCount("1").test()
                .assertHasValue()
                .assertValue(3)
    }

    @Test
    fun testGetPostList() {
        getPostListUseCase.getPostList().test()
                .assertHasValue()
                .assertValue {
                    it.size == 3
                }
    }

    @Test
    fun testGetPostDetails() {
        getPostDetailsUseCase.getPostDetails("2").test()
                .assertHasValue()
                .assertValue {
                    val postDetails = it
                    postDetails.username == "user3"
                }
    }

L'erreur que j'obtiens est la suivante lorsque le koin tente de récupérer la valeur injectée

    java.lang.NoClassDefFoundError: org/koin/test/KoinTest$DefaultImpls
    at com.app.UseCaseUnitTests.getKoin(UseCaseUnitTests.kt:37)
    at com.app.UseCaseUnitTests$$special$$inlined$inject$3.invoke(KoinComponent.kt:53)
    at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
    at com.app.UseCaseUnitTests.getGetPostDetailsUseCase(UseCaseUnitTests.kt)
    at com.app.UseCaseUnitTests.testGetPostDetails(UseCaseUnitTests.kt:120)
    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.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    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)
    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 com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)

J'ai même essayé l'exemple d'ici https://insert-koin.io/docs/1.0/quick-references/koin-test/

class MyTest : KoinTest {

    class ComponentA
    class ComponentB(val a: ComponentA)

    val appModule = module {
        single { ComponentA() }
        single { ComponentB(get()) }
    }

    // Lazy inject property
    val componentB : ComponentB by inject()

    @Test
    fun `should inject my components`() {
        startKoin(listOf(appModule))

        // directly request an instance
        val componentA = get<ComponentA>()

        assertNotNull(componentA)
        assertEquals(componentA, componentB.a)
    }
}

No Joy, même erreur

3voto

jonney Points 3115

J'ai corrigé ce problème en utilisant la dernière version de koin 1.0.2.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X