【问题标题】:Mockito is not recognized by Android (Kotlin)Android (Kotlin) 无法识别 Mockito
【发布时间】:2019-07-17 15:21:45
【问题描述】:

这是我的课堂测试:

private const val FAKE_STRING = "APP NAME"

@RunWith(MockitoJUnitRunner::class)
class UnitTestSample {
    @Mock
    private lateinit var mockContext: Context

    @Test
    fun readStringFromContext_LocalizedString() {
        // Given a mocked Context injected into the object under test...
        `when`(mockContext.getString(R.string.app_name))
            .thenReturn(FAKE_STRING)
        val myObjectUnderTest = ClassUnderTest(mockContext)

        // ...when the string is returned from the object under test...
        val result: String = myObjectUnderTest.getHelloWorldString()

        // ...then the result should be the expected one.
        assertThat(result, `is`(FAKE_STRING))
    }
}

这是我的 gradle.build.kt (Kotlin DSL) 的一部分:

plugins {
    id("com.android.application")
    kotlin("android")
    kotlin("kapt")
    kotlin("android.extensions")
    id("com.onesignal.androidsdk.onesignal-gradle-plugin")
    jacoco
    maven
}

dependencies {
        ...
        //Test base
        testImplementation("junit:junit:4.12")
        testImplementation("org.junit.jupiter:junit-jupiter-api:5.0.3")
        testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.0.3")
        androidTestImplementation("androidx.test:runner:1.2.0")
        androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")

        //Unit Tests
        testImplementation("org.mockito:mockito-core:3.0.0")
        testImplementation("org.mockito:mockito-inline:3.0.0") //support for kotlin final classes

        //Android UI Test
        androidTestImplementation("org.robolectric:robolectric:3.7.1")
}

如您所见,Android Studio 无法识别 Mockito。我已经导入了org.mockito.junit.MockitoJUnitRunner

我正在运行这个示例单元测试

src/test/java/.../UnitTestSample.kt

你知道如何让它发挥作用吗?

编辑(解决方案):

我终于在 cmets 部分的帮助下让它工作了。问题是由插件部分的“maven”插件导入引起的,我没有看到这一点,因为我下载的用于将 Gradle 转换为 DSL Kotlin 的基础项目使这些插件正常工作。正如@MartinZeitler 所说,这不知何故导致 Mockito 在编译时不可用。根据@second,“Maven 的运行时不会转换为 gradle 的 runtimeOnly,而是编译”。

【问题讨论】:

  • 你错过了import org.mockito.junit.MockitoJUnitRunner。这可能是由于文件中的其他错误导致自动解析不起作用。或者你的 gradle 依赖项可能会丢失一些东西。
  • @dharms 我已经导入了它,但它无法识别,但在 import org.mockito.junit.MockitoJUnitRunner 中 mockito 是红色的
  • 您使用 JUnit 4 还是 5 - 似乎您的导入是两者的混合?如果它是 5,您可能想尝试扩展。
  • @second 我使用 JUnit 5,JUnit 4 导入只是为了测试一些东西。当我设置 Jacoco 时,它要求我提供一个 TestEngine 来运行覆盖测试,所以我导入了一个 JUnit 5。但我认为完全没有问题。我可以同时删除它或使用 JUnit Vintage(它允许在 JUnit 4 和 3 上实现逆向兼容)。

标签: android kotlin mockito


【解决方案1】:

错误信息很清楚:an annotation argument must be a compile time argument

testImplementation 替换为:

debugImplementation "org.mockito:mockito-android:3.2.4"
debugImplementation "org.mockito:mockito-inline:3.2.4"

【讨论】:

  • @second @RunWith 是注解,MockitoJUnitRunner 是参数;由于某种原因,并非两者都在编译时可用,因为它应该是。
  • @MartinZeitler 这就是问题所在!在你们的帮助下,我想通了研究插件
  • @DimasMendes 在再次找到我自己的答案后发现只有debugImplementation 有效。
【解决方案2】:

编辑:整理答案


对于 JUnit5 和 mockito,使用以下依赖项(或更新的)和范围:

    testImplementation("org.junit.jupiter:junit-jupiter-api:5.4.2")
    compile("org.junit.jupiter:junit-jupiter-engine:5.4.2")
    testImplementation("org.mockito:mockito-core:3.0.0")
    testImplementation("org.mockito:mockito-junit-jupiter:3.0.0")
    testImplementation("org.mockito:mockito-inline:3.0.0")

在您的测试中,使用 Extension 而不是 Runner(适用于 JUnit 4)。

@ExtendWith(MockitoExtension::class)


当使用 5.0.3 的 JUnit 5 依赖项运行时,出现以下错误,因此请考虑升级到较新的版本(如上面的依赖项所示)。

java.lang.NoSuchMethodError: 
org.junit.platform.commons.support.AnnotationSupport.findAnnotation(Ljava/util/Optional;Ljava/lang/Class;)Ljava/util/Optional;
...
Suppressed: java.lang.NullPointerException
at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:214)

对于 maven 到 gradle 的转换,我使用了这个网站 https://sagioto.github.io/maven2gradle/

【讨论】:

  • 这个链接只是重复了我写的内容......当不使用 Android DSL,但默认使用 Java 时。
  • @second 我添加了testImplementation ("org.mockito:mockito-junit-jupiter:3.0.0")@ExtendWith(MockitoExtension::class) 并删除了对JUnit 4 的依赖。但现在它告诉我Unsolved reference: MockitoExtension::class
  • @second 我终于明白了!!!在我的插件部分,我添加了“maven”(我不知道为什么),这导致了错误。我将在答案末尾添加详细信息
  • 其实我刚刚发现maven的runtime不会转换成gradle的runtimeOnly而是compile。所以Martin Zeitler 关于那部分可能是正确的。
  • 是的,我有这个洞察力是因为你们所有人和你们的 cmets。谢谢你们!
猜你喜欢
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 2022-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
相关资源
最近更新 更多