简体   繁体   English

Koin Android 测试

[英]Koin Android Test

I have a problem with Koin & "androidTest".我对 Koin 和“androidTest”有问题。 Because androidTest starts the Application i don't need to start Koin by myself in the test.因为 androidTest 启动应用程序,所以我不需要在测试中自己启动 Koin。

Now i need to inject a mock service.现在我需要注入一个模拟服务。 The problem is, that i inject inside of a method with get() inside of a singleton class and this is not working via constructor injection because the injected object can have different implementations.问题是,我在单例类中使用 get() 在方法内部注入,这不能通过构造函数注入工作,因为注入的对象可以有不同的实现。

My idea was to declare what i need this way:我的想法是通过这种方式声明我需要什么:

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

But this will be applied on all tests.但这将应用于所有测试。 That's why an other test, which checks if the correct class was injected failed.这就是检查是否注入了正确类的其他测试失败的原因。

I also tried to use stopKoin(), startKoin(listOf(appModule)) in the @After method, but with this the dependency injection doesn't work anymore in later tests.我还尝试在 @After 方法中使用 stopKoin()、startKoin(listOf(appModule)),但是这样依赖注入在以后的测试中不再起作用。

Is there a way to declare the mock only for one test?有没有办法只为一个测试声明模拟?

Here is how I do it in my Android Tests:以下是我在 Android 测试中的做法:

In a parent test class, I use these methods for setup and teardown:在父测试类中,我使用这些方法进行设置和拆卸:

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

@After fun stopKoinAfterTest() = stopKoin()

My appcomponent contains all modules needed for the dependency tree.我的 appcomponent 包含依赖树所需的所有模块。

Then, when I want to mock a dependency for a specific test, I use something like this:然后,当我想模拟特定测试的依赖项时,我使用如下内容:

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

You will need to add a new mock declaration for each test if you wish to swap a dependency with a mock.如果您希望将依赖项与模拟交换,则需要为每个测试添加一个新的模拟声明。

To declare mock only for one test you can use loadKoinModules()要仅为一项测试声明模拟,您可以使用loadKoinModules()

You can't call the startKoin() function more than once.您不能多次调用 startKoin() 函数。 But you can use directly the loadKoinModules() functions.但是您可以直接使用 loadKoinModules() 函数。

So this way your definition will override default one所以这样你的定义将覆盖默认的

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

Also, don't forget to implement KoinTest interface in you test class另外,不要忘记在你的测试类中实现KoinTest接口

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM