Как получить контекст Android в мультиплатформенном тесте Android Kotlin? - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть следующий 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 , но он не использует контекст Android, поэтому не имеет этого исключения.

PS.Я могу запускать общие тесты без каких-либо проблем.

1 Ответ

0 голосов
/ 24 апреля 2019

Мне удалось решить эту проблему с помощью RobolectricTestRunner и RuntimeEnvironment.application.applicationContext, чтобы получить контекст

Добавить в gradle:

api 'org.robolectric:robolectric:4.2'

Затем использовать

@RunWith(RobolectricTestRunner::class)

...

val context = RuntimeEnvironment.application.applicationContext
...