BeanInstanceCreationException: не удается создать определение для одного - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь запустить инструментальные тесты в папке androidTest, используя Пример создателя Koin .Каждый тест проходит, если я запускаю их один за другим.Но когда я запускаю их все сразу, только первые проходы.Остальное не удалось с: BeanInstanceCreationException: Can't create definition for 'Single [name='MovieDatabase',....Вот мои тесты:

class MovieDatabaseTest: AutoCloseKoinTest() {

@get:Rule val instantExecutorRule = InstantTaskExecutorRule()
private val movieDatabase: MovieDatabase by inject()
private val movieDAO: DetailDao by inject()

private val testModule = module {
    single(override = true) {
        Room.inMemoryDatabaseBuilder(androidContext (), MovieDatabase::class.java)
                .allowMainThreadQueries()
                .build()
    }
}

@Before fun setUp() {
    loadKoinModules(testModule)
}

@After fun tearDown() {
    movieDatabase.close()
}

@Test
fun saveMovieTest() {
    val observer = mock<Observer<Movie>>()
    val date = Date()
    val movie = buildMovie(1, dateUpdate = date)
    val captor = ArgumentCaptor.forClass(Movie::class.java)

    movieDAO.saveMovie(movie)
    val movieLD = movieDAO.getMovie(1)
    movieLD.observeForever(observer)

    verify(observer).onChanged(captor.capture())
    assertEquals(captor.value, buildMovie(1, dateUpdate = date))
}

@Test
fun likeTest() {
    val movie = buildMovie(1)

    movieDAO.saveMovie(movie)
    movieDAO.like(1, true)
    val movieLD = movieDAO.getMovie(1)
    movieLD.observeForever {
        assert(it.liked)
    }
}

@Test
fun getMovieByDateTest() {
    val dateUpdate = Date()
    val queryDate = Date(System.currentTimeMillis() - 3600 * 1000)
    val movie = buildMovie(1, dateUpdate = dateUpdate)
    movieDAO.saveMovie(movie)    

    val savedMovie = movieDAO.getMovieByDate(1, queryDate)
    assertNotNull(savedMovie)
    }
}

Трассировка стека ошибок:

    org.koin.error.BeanInstanceCreationException: Can't create definition for 'Single [name='MovieDatabase',class='us.kostenko.architecturecomponentstmdb.common.database.MovieDatabase']' due to error :
No compatible definition found. Check your module definition
org.koin.core.bean.BeanRegistry.checkedResult(BeanRegistry.kt:120)
org.koin.core.bean.BeanRegistry.retrieveDefinition(BeanRegistry.kt:87)
org.koin.core.instance.InstanceRegistry.findDefinition(InstanceRegistry.kt:125)
org.koin.core.instance.InstanceRegistry.access$findDefinition(InstanceRegistry.kt:39)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$1.invoke(InstanceRegistry.kt:91)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$1.invoke(InstanceRegistry.kt:39)
org.koin.core.time.DurationKt.logDuration(Duration.kt:11)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:90)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:39)
org.koin.core.time.DurationKt.measureDuration(Duration.kt:19)
org.koin.core.instance.InstanceRegistry.proceedResolution(InstanceRegistry.kt:87)
org.koin.core.instance.InstanceRegistry.resolve(InstanceRegistry.kt:61)
org.koin.android.ext.koin.ContextExtKt.androidContext(ContextExt.kt:42)
us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest$testModule$1$1.invoke(MovieDatabaseTest.kt:34)
us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest$testModule$1$1.invoke(MovieDatabaseTest.kt:26)
org.koin.core.instance.holder.InstanceHolder$DefaultImpls.create(InstanceHolder.kt:17)
org.koin.core.instance.holder.SingleInstanceHolder.create(SingleInstanceHolder.kt:10)
org.koin.core.instance.holder.SingleInstanceHolder.get(SingleInstanceHolder.kt:19)
org.koin.core.instance.InstanceFactory.retrieveInstance(InstanceFactory.kt:53)
org.koin.core.instance.InstanceRegistry$resolveInstance$1.invoke(InstanceRegistry.kt:138)
org.koin.core.instance.InstanceRegistry$resolveInstance$1.invoke(InstanceRegistry.kt:39)
org.koin.core.stack.ResolutionStack.resolve(ResolutionStack.kt:44)
org.koin.core.instance.InstanceRegistry.resolveInstance(InstanceRegistry.kt:137)
org.koin.core.instance.InstanceRegistry.access$resolveInstance(InstanceRegistry.kt:39)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$2.invoke(InstanceRegistry.kt:98)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$2.invoke(InstanceRegistry.kt:39)
org.koin.core.time.DurationKt.logDuration(Duration.kt:11)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:97)
org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:39)
org.koin.core.time.DurationKt.measureDuration(Duration.kt:19)
org.koin.core.instance.InstanceRegistry.proceedResolution(InstanceRegistry.kt:87)
org.koin.core.instance.InstanceRegistry.resolve(InstanceRegistry.kt:61)
us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest$$special$$inlined$inject$1.invoke(KoinComponent.kt:143)
kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest.getMovieDatabase(Unknown Source:7)
us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest.tearDown(MovieDatabaseTest.kt:45)
java.lang.reflect.Method.invoke(Native Method)
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:80)
org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
org.junit.rules.RunRules.evaluate(RunRules.java:20)
org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
org.junit.runners.ParentRunner.run(ParentRunner.java:363)
org.junit.runners.Suite.runChild(Suite.java:128)
org.junit.runners.Suite.runChild(Suite.java:27)
org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
org.junit.runners.ParentRunner.run(ParentRunner.java:363)
org.junit.runner.JUnitCore.run(JUnitCore.java:137)
org.junit.runner.JUnitCore.run(JUnitCore.java:115)
androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2075)
at org.koin.core.instance.holder.InstanceHolder$DefaultImpls.create(InstanceHolder.kt:23)
at org.koin.core.instance.holder.SingleInstanceHolder.create(SingleInstanceHolder.kt:10)
at org.koin.core.instance.holder.SingleInstanceHolder.get(SingleInstanceHolder.kt:19)
at org.koin.core.instance.InstanceFactory.retrieveInstance(InstanceFactory.kt:53)
at org.koin.core.instance.InstanceRegistry$resolveInstance$1.invoke(InstanceRegistry.kt:138)
at org.koin.core.instance.InstanceRegistry$resolveInstance$1.invoke(InstanceRegistry.kt:39)
at org.koin.core.stack.ResolutionStack.resolve(ResolutionStack.kt:44)
at org.koin.core.instance.InstanceRegistry.resolveInstance(InstanceRegistry.kt:137)
at org.koin.core.instance.InstanceRegistry.access$resolveInstance(InstanceRegistry.kt:39)
at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$2.invoke(InstanceRegistry.kt:98)
at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1$2.invoke(InstanceRegistry.kt:39)
at org.koin.core.time.DurationKt.logDuration(Duration.kt:11)
at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:97)
at org.koin.core.instance.InstanceRegistry$proceedResolution$$inlined$synchronized$lambda$1.invoke(InstanceRegistry.kt:39)
at org.koin.core.time.DurationKt.measureDuration(Duration.kt:19)
at org.koin.core.instance.InstanceRegistry.proceedResolution(InstanceRegistry.kt:87)
at org.koin.core.instance.InstanceRegistry.resolve(InstanceRegistry.kt:61)
at us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest$$special$$inlined$inject$1.invoke(KoinComponent.kt:143)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest.getMovieDatabase(Unknown Source:7)
at us.kostenko.architecturecomponentstmdb.details.repository.MovieDatabaseTest.tearDown(MovieDatabaseTest.kt:45)
at java.lang.reflect.Method.invoke(Native Method)
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 androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:80)
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.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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 org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2075)

Здесь также приведены определения моих модулей non-testing, которые я запускаю с помощью startKoin(this, listOf(baseModule, movieDetailModule)) из моей реализации приложения:

    val baseModule = module {

    factory<Coroutines> { AndroidCoroutines() }

    single { Room.databaseBuilder(androidContext(), MovieDatabase::class.java, "movies-db")
            .fallbackToDestructiveMigration().build() }

    single { TmdbRetrofitBuilder(androidContext()).buildRetrofit() }
}

val movieDetailModule = module {

    single { get<MovieDatabase>().detailDao() }

    single<MovieWebService>{ get<Retrofit>().create(MovieWebService::class.java) }

    single<MovieDetailRepository>{ MovieDetailRepositoryImpl(get(), get(), get()) }

    viewModel { MovieDetailViewModel(get(), get()) }
}

Кажется, это как-то связано со строкой movieDatabase.close(), но я не могу понять, какая конфигурация будет работать между тестами.

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

У меня была похожая проблема, Попробуйте просто добавить ## зависимость ##

// Room implementation "android.arch.persistence.room:runtime:1.1.1" kapt "android.arch.persistence.room:compiler:1.1.1"

0 голосов
/ 23 января 2019

У меня была похожая проблема.Я предполагаю, что это связано с использованием androidContext() или androidApplication в определении модуля.

Я решил проблему, выполнив следующее:

 @Before()
 fun before() {
     val context = ApplicationProvider.getApplicationContext<Application>()
     StandAloneContext.loadKoinModules(baseAppModule).with(context)
 }

То же самое делает startKoin метод в файле библиотеки расширения Android Koin ComponentCallbacksExt.Kt

Попробуйте !!!

...