2

当我尝试开始我的一项junit测试时,由于多个错误,所有测试都失败了。这是因为 myApplication class中有一些变量,这些变量在“正常”应用程序启动时初始化,但不是在我开始测试时初始化。注释掉变量可能会有所帮助,但这是一个丑陋的解决方案,在开始测试时总是注释掉一些东西。

应用类

@HiltAndroidApp
@InternalCoroutinesApi
class App : Application(), Configuration.Provider {
    @Inject lateinit var workerFactory: HiltWorkerFactory
    @Inject lateinit var workerList: WorkerList
    override fun onCreate() {
        super.onCreate()
        plantTimberTree()
        enableOfflinePersistence()
        workerList.startDownloadDocumentWork()
    }

    override fun getWorkManagerConfiguration(): Configuration =
        Configuration.Builder().setWorkerFactory(workerFactory).build()
}

private fun plantTimberTree() = Timber.plant(Timber.DebugTree())

private fun enableOfflinePersistence() {
    val settings = firestoreSettings { isPersistenceEnabled = true }
    Firebase.firestore.firestoreSettings = settings
}

测试用例

@RunWith(RobolectricTestRunner::class)
@Config(maxSdk = Build.VERSION_CODES.P, minSdk = Build.VERSION_CODES.P)
class EmailViewModelTest {


}

错误堆栈跟踪(没有任何评论)

java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process null. Make sure to call FirebaseApp.initializeApp(Context) first.

    at com.google.firebase.FirebaseApp.getInstance(FirebaseApp.java:184)
    at com.google.firebase.firestore.FirebaseFirestore.getInstance(FirebaseFirestore.java:91)
    at com.google.firebase.firestore.ktx.FirestoreKt.getFirestore(Firestore.kt:32)
    at com.example.app.AppKt.enableOfflinePersistence(App.kt:44)
    at com.example.app.AppKt.access$enableOfflinePersistence(App.kt:1)
    at com.example.app.App.onCreate(App.kt:24)
    at org.robolectric.android.internal.AndroidTestEnvironment.lambda$installAndCreateApplication$0(AndroidTestEnvironment.java:288)
    at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:75)
    at org.robolectric.android.internal.AndroidTestEnvironment.installAndCreateApplication(AndroidTestEnvironment.java:288)
    at org.robolectric.android.internal.AndroidTestEnvironment.setUpApplicationState(AndroidTestEnvironment.java:171)
    at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:319)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:254)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

错误堆栈跟踪(注释掉“enableOfflicePersistence”时)

kotlin.UninitializedPropertyAccessException: lateinit property workerList has not been initialized

    at com.example.app.App.onCreate(App.kt:25)
    at org.robolectric.android.internal.AndroidTestEnvironment.lambda$installAndCreateApplication$0(AndroidTestEnvironment.java:288)
    at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:75)
    at org.robolectric.android.internal.AndroidTestEnvironment.installAndCreateApplication(AndroidTestEnvironment.java:288)
    at org.robolectric.android.internal.AndroidTestEnvironment.setUpApplicationState(AndroidTestEnvironment.java:171)
    at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:319)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:254)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

有没有办法确定测试是否已经开始?我应该如何更改我的应用程序类才能让我的测试再次运行?

我感谢每一个帮助,谢谢。

4

2 回答 2

1

我看到你正在使用 RobolectricTestRunner。

有几种不同的方法可以解决在 Robolectric 测试期间 FirebaseApp 进入奇怪状态的问题,以及如果您的 Application 类已正常初始化它会如何表现。

(1) 您可以使用 Robolectric 指定一个特殊的测试应用程序上下文,以使用它对 Firebase 执行任何操作。

(2) 您可以使用 Roboelectric 为 FirebaseApp 创建一个影子类,该类以您希望的任何方式运行。(这是一个示例,其中我让影子类捕获您引用的异常并初始化 Firebase。)

为 FirebaseApp 编写影子类的优势在于,它可以配置为干预您的代码可能访问 FirebaseApp 的任何方式,并且robolectric.properties 文件可以配置您的整个测试包。

于 2020-10-30T16:24:11.807 回答
0

这可以通过实现 Roboelectric 库来解决,因为它提供了运行测试的 android 环境。

检查以下链接以获取详细说明如何使用它。我发现它非常有用。

https://codelabs.developers.google.com/codelabs/advanced-android-kotlin-training-testing-basics/#0

于 2020-10-11T14:52:43.500 回答