【问题标题】:Koin Android TestKoin Android 测试
【发布时间】:2018-10-15 14:38:52
【问题描述】:

我对 Koin 和“androidTest”有疑问。 因为androidTest启动了Application,所以测试中不需要自己启动Koin。

现在我需要注入一个模拟服务。问题是,我在一个单例类中使用 get() 注入了一个方法,这不能通过构造函数注入工作,因为注入的对象可以有不同的实现。

我的想法是用这种方式声明我需要什么:

declare {
        factory<Webservice>(override = true) { mockWebservice }
    }

但这将应用于所有测试。这就是为什么另一个检查是否注入了正确的类的测试失败的原因。

我也尝试在 @After 方法中使用 stopKoin()、startKoin(listOf(appModule)),但是这样依赖注入在以后的测试中不再起作用。

有没有办法只为一个测试声明模拟?

【问题讨论】:

  • 所以你只想为那个测试声明mockWebService
  • 是的,但看起来如果没有用于测试的特殊应用程序类或类似的东西是不可能的

标签: android dependency-injection kotlin koin


【解决方案1】:

这是我在 Android 测试中的做法:

在父测试类中,我使用这些方法进行设置和拆卸:

@Before fun startKoinForTest() {
    if (GlobalContext.getOrNull() == null) {
        startKoin {
            androidLogger()
            androidContext(application)
            modules(appComponent)
        }
    }
}

@After fun stopKoinAfterTest() = stopKoin()

我的 appcomponent 包含依赖关系树所需的所有模块。

然后,当我想模拟特定测试的依赖项时,我会使用这样的东西:

declareMock<TripApi> { given(this.fetch(any())).willReturn(TestData.usaTrip) }

如果您希望将依赖项与模拟交换,则需要为每个测试添加一个新的模拟声明。

【讨论】:

    【解决方案2】:

    要为一项测试声明模拟,您可以使用loadKoinModules()

    您不能多次调用 startKoin() 函数。但是你可以直接使用 loadKoinModules() 函数。

    所以这样你的定义会覆盖默认的

    loadKoinModules(module {
        factory<Webservice>(override = true) { mockWebservice }
    })
    

    另外,不要忘记在你的测试类中实现KoinTest 接口

    【讨论】:

    • 感谢您的回答,但如果我这样做,其他类中的其他测试将失败:demoMode.activate() val webservice: Webservice = get() assertTrue(webservice is DemoWebservice)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多