java.lang.AbstractMethodError:使用Mockito在Kotlin上运行espresso时的抽象方法

时间:2016-07-01 04:18:36

标签: mockito kotlin android-espresso

我有一个使用mockito的器乐浓缩咖啡测试。测试类如下。

import android.support.test.InstrumentationRegistry
import android.support.test.rule.ActivityTestRule

import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.rules.TestRule

import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.espresso.matcher.ViewMatchers.withText
import org.mockito.Mockito.`when`

class MainActivityTest {

    val component = TestComponentRule(InstrumentationRegistry.getTargetContext())
    val main = ActivityTestRule(MainActivity::class.java, false, false)
    // TestComponentRule needs to go first so we make sure the ApplicationTestComponent is set
    // in the Application before any Activity is launched.
    @JvmField @Rule
    var chain: TestRule = RuleChain.outerRule(component).around(main)

    @Before
    fun setUp() {
    }

    @Test
    fun simpleTrueTest() {
        `when`(component.mockInjectedData.status).thenReturn(true)
        main.launchActivity(null)

        onView(withId(R.id.txt_myview)).check(matches(withText("True")))
    }

    @Test
    fun simpleFalseTest() {
        `when`(component.mockInjectedData.status).thenReturn(false)
        main.launchActivity(null)

        onView(withId(R.id.txt_myview)).check(matches(withText("False")))
    }

}

我的TestComponentRule如下

import android.content.Context

import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement

class TestComponentRule(val context: Context) : TestRule {

    private var mTestComponent: ApplicationTestComponent? = null

    val mockInjectedData: InjectedData
        get() = mTestComponent!!.dataManager()

    private fun setupDaggerTestComponentInApplication() {
        val application = MainApplication[context]
        mTestComponent = DaggerApplicationTestComponent.builder().applicationTestModule(ApplicationTestModule(application)).build()
        application.component = mTestComponent as ApplicationComponent
    }

    override fun apply(base: Statement, description: Description): Statement {
        return object : Statement() {
            @Throws(Throwable::class)
            override fun evaluate() {
                try {
                    setupDaggerTestComponentInApplication()
                    base.evaluate()
                } finally {
                    mTestComponent = null
                }
            }
        }
    }
}

我的Dagger TestModule

import android.app.Application

import javax.inject.Singleton

import dagger.Module
import dagger.Provides
import org.mockito.Mockito.mock

@Module
class ApplicationTestModule(protected val mApplication: Application) {

    @Provides
    internal fun provideApplication(): Application {
        return mApplication
    }

    @Provides
    @Singleton
    internal fun provideInjectedData(): InjectedData {
        return mock(InjectedData::class.java)
    }
}

我的build.gradle文件如下

dependencies {
    final SUPPORT_LIBRARY_VERSION = '23.4.0'
    final DAGGER_VERSION = '2.2'
    final DEXMAKER_VERSION = '1.4'
    final MOCKITO_VERSION = '1.10.19'
    final ESPRESSO_VERSION = '2.2.1'
    final JUNIT_VERSION = '4.12'
    final RUNNER_VERSION = '0.4'

    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile "junit:junit:$JUNIT_VERSION"

    compile "com.android.support:appcompat-v7:$SUPPORT_LIBRARY_VERSION"
    compile "com.google.dagger:dagger:$DAGGER_VERSION"
    kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
    kaptAndroidTest "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
    apt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
    androidTestApt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
    provided 'org.glassfish:javax.annotation:10.0-b28'

    compile "org.jetbrains.kotlin:kotlin-stdlib:$KOTLIN_VERSION"


    androidTestCompile "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION"
    androidTestCompile("com.android.support.test.espresso:espresso-contrib:$ESPRESSO_VERSION") {
        exclude group: 'com.android.support', module: 'appcompat'
        exclude group: 'com.android.support', module: 'support-v4'
        exclude group: 'com.android.support', module: 'recyclerview-v7'
    }
    androidTestCompile "com.android.support.test.espresso:espresso-core:$ESPRESSO_VERSION"
    androidTestCompile "com.android.support.test.espresso:espresso-intents:$ESPRESSO_VERSION"
    androidTestCompile "com.android.support.test:runner:$RUNNER_VERSION"
    androidTestCompile "com.android.support.test:rules:$RUNNER_VERSION"
    androidTestCompile "org.mockito:mockito-core:$MOCKITO_VERSION"
    androidTestCompile "com.crittercism.dexmaker:dexmaker:$DEXMAKER_VERSION"
    androidTestCompile "com.crittercism.dexmaker:dexmaker-dx:$DEXMAKER_VERSION"
    androidTestCompile "com.crittercism.dexmaker:dexmaker-mockito:$DEXMAKER_VERSION"

    androidTestCompile ("com.nhaarman:mockito-kotlin:0.4.1") {
        exclude group: "org.jetbrains.kotlin", module: 'kotlin-stdlib'
    }
}

当我触发Instrumentation测试时,

上的错误
        `when`(component.mockInjectedData.status).thenReturn(true)

        `when`(component.mockInjectedData.status).thenReturn(false)

错误

java.lang.AbstractMethodError: abstract method "org.mockito.plugins.MockMaker$TypeMockability org.mockito.plugins.MockMaker.isTypeMockable(java.lang.Class)"
at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:26)
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:21)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:167)
at org.mockito.internal.creation.MockSettingsImpl.confirm(MockSettingsImpl.java:161)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:54)
at org.mockito.Mockito.mock(Mockito.java:1449)
at org.mockito.Mockito.mock(Mockito.java:1362)    

1 个答案:

答案 0 :(得分:0)

显然从我的build.gradle中删除了下面的Mockito-Kotlin库来解决问题

androidTestCompile ("com.nhaarman:mockito-kotlin:0.4.1") {
    exclude group: "org.jetbrains.kotlin", module: 'kotlin-stdlib'
}

<强>已更新

根据https://github.com/nhaarman/mockito-kotlin/issues/46

向nhaarman报告此问题