如何在Kotlin跨平台Android测试中获取Android上下文?

时间:2019-02-28 06:54:23

标签: android testing kotlin kotlin-multiplatform

我有以下build.gradle文件:

plugins {
    id 'com.android.library'
    id 'kotlin-multiplatform' version '1.3.20'
    id "org.jetbrains.kotlin.kapt" version "1.3.20"
}

group 'com.company.project'
version '0.8'

apply plugin: 'maven-publish'

android {
    compileSdkVersion 27
    defaultConfig {
        minSdkVersion 15
    }
    buildTypes {
        release {
            minifyEnabled false
        }
    }
}

kotlin {
    jvm()
    wasm32('wasm')
    android()

    sourceSets {
        commonMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
                implementation "org.jetbrains.kotlin:kotlin-reflect"
            }
        }
        commonTest {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-test-common'
                implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common'
            }
        }
        commonJvmMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
            }
            dependencies {
                implementation 'net.sf.trove4j:trove4j:3.0.3'

            }
        }
        jvmMain {
            dependsOn commonJvmMain
        }
        jvmTest {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-test'
                implementation 'org.jetbrains.kotlin:kotlin-test-junit'
            }
        }
        androidMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
                implementation "android.arch.persistence.room:runtime:1.0.0"
            }
        }
        androidTest {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-test'
                implementation 'org.jetbrains.kotlin:kotlin-test-junit'

                implementation "android.arch.persistence.room:runtime:1.0.0"
            }
        }
    }
}

dependencies {
    androidTestImplementation 'junit:junit:4.12'
    androidTestImplementation 'org.jetbrains.kotlin:kotlin-test'
    androidTestImplementation 'org.jetbrains.kotlin:kotlin-test-junit'

    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    kapt "android.arch.persistence.room:compiler:1.0.0"
}

src/androidTest/kotlin/..中,我进行了以下测试:

package com.company.project.test

import android.arch.persistence.room.Room
import android.support.test.InstrumentationRegistry
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import kotlin.test.*

@RunWith(JUnit4::class)
class DbDaoTest {

    private val map = memEffMapOf<String, String>()

    @BeforeTest
    fun setUp() {
        val context = InstrumentationRegistry.getTargetContext() // Crash here
        val db = Room
            .inMemoryDatabaseBuilder(context, MapDatabase::class.java)
            .build()
        MapDaoHolder.dao = db.mapDao()
    }

    @Test
    fun testAdd() {
        ...
    }
}

它在setUp()中崩溃:

java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.

    at android.support.test.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:44)
    at android.support.test.InstrumentationRegistry.getTargetContext(InstrumentationRegistry.java:82)
    at com.company.project.test.DbDaoTest.setUp(DbMapFactoryTest.kt:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    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 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    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.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

我该怎么办?我研究了JetBrains mpp android test example,但它不使用android上下文,因此没有此异常。

PS。我能够运行普通测试而没有任何问题。

1 个答案:

答案 0 :(得分:0)

我能够通过使用RobolectricTestRunner和RuntimeEnvironment.application.applicationContext来获取上下文来解决此问题

添加到gradle:

api 'org.robolectric:robolectric:4.2'

然后使用

@RunWith(RobolectricTestRunner::class)

...

val context = RuntimeEnvironment.application.applicationContext