6

使用 koin-2.0.1 进行 Android 测试,尽管每个测试都单独通过,但无法同时测试所有 3 个测试。

class NumberFormatterUtilImplTest : KoinTest {

    private val numberFormatterUtil: NumberFormatterUtilImpl by inject()

    @Before
    fun setUp() {
        startKoin { modules(utilsModule) }
    }

    @Test
    fun `does formatter returns two digit faction if supplied one digit value`() {
        val result = numberFormatterUtil.getAdjustedCurrencyRate(18.0)
        Assert.assertEquals(result, 18.00, 1.0)
    }

    @Test
    fun `does formatter returns two digit faction if supplied multiple digits value`() {
        val result = numberFormatterUtil.getAdjustedCurrencyRate(18.12343)
        Assert.assertEquals(result, 18.12, 1.0)
    }

    @Test
    fun `does formatter returns rounded two digit faction if supplied multiple digits value`() {
        val result = numberFormatterUtil.getAdjustedCurrencyRate(18.12876)
        Assert.assertEquals(result, 18.13, 1.0)
    }
}

运行类级别测试结果如下:

org.koin.core.error.KoinAppAlreadyStartedException: A Koin Application has already been started

任何输入都会有所帮助,谢谢。

4

5 回答 5

20

一种常见的做法是将@Before设置与@After清理配对。您可以stopKoin()在那里调用,以便下次调用startKoin()再次起作用:

@After
fun tearDown() {
    stopKoin()
}
于 2019-07-15T14:10:56.223 回答
12

作为该方法的替代@After方法,您还可以使用AutoCloseKoinTest. 如文档中所述

扩展 Koin 测试 - 嵌入 autoclose @after 方法以在每次测试后关闭 Koin

而不是扩展KoinTest,您可以扩展AutoCloseKoinTest,它会为您做事后测试。

于 2019-07-22T00:49:44.300 回答
5

在 @Before 和 @After 方法上调用 stopKoin(),如下所示:

import com.my.example.appModule
import android.os.Build
import androidx.test.core.app.ApplicationProvider
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.test.KoinTest
import org.koin.test.inject
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import java.util.*

@Config(sdk = [Build.VERSION_CODES.LOLLIPOP])
@RunWith(RobolectricTestRunner::class)
class SomeRepositoryTest: KoinTest {

    // Return Completable of RxJava
    private val repository: SomeRepository by inject()

    @Before
    fun before() {
        stopKoin() // to remove 'A Koin Application has already been started'
        startKoin {
            androidContext(ApplicationProvider.getApplicationContext())
            modules(appModule)
        }
    }

    @After
    fun after() {
        stopKoin()
    }

    @Test
    fun testSomething() {

        repository.insert("data").blockingAwait()

        assert(true)
    }
}
于 2019-09-23T06:40:58.143 回答
3

解决此问题的另一种方法是onTerminate在您启动 Koin 的应用程序中覆盖它

override fun onTerminate() {
    super.onTerminate()     
    stopKoin()              
}

通过这种方式,您不必AutoCloseKoinTest在每个班级测试中使用或关闭它@after

于 2019-09-11T23:39:04.140 回答
0

实现抽象 AutoCloseKoinTest 类将在每次测试后自动停止 Koin。

以下是 Robolectric 的示例:

@RunWith(RoboelectricTestRunner::class)
class MyTest : AutoCloseKoinTest() {
   private val appContext = ApplicationProvider.getApplicationContext<APPNAME>()

   @Before
   fun setup() {
      // use appContext as needed
   }
}
于 2020-06-04T21:30:45.907 回答