带有Mock ViewModel的NoBeanDefFoundException,使用Koin,Espresso进行测试

我一直在尝试使用Espresso作为DI工具进行简单的Koin单元测试。这是我在build.gradle

中使用的依赖项
    // testing with Koin
    // because of this
    // https://github.com/InsertKoinIO/koin/pull/604/commits/69391bc378bbb9007b9d82c46537e7d753be7ea3
    androidTestImplementation 'org.mockito:mockito-android:3.1.0'
    androidTestImplementation ("org.koin:koin-test:$koin_version") {
        exclude group: 'org.mockito'
    }

    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    // stuff like activityTestRule
    androidTestImplementation 'androidx.test:rules:1.2.0'
    // AndroidJUnit4
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    // test runner
    androidTestImplementation 'androidx.test:runner:1.2.0'

我的ViewModel声明

open class LoginViewModel(private val apiService: MockApiService) : ViewModel() {
..
..
}

这是它在“活动”中的注入方式

private val loginViewModel: LoginViewModel by viewModel()

我的自定义TestRunner以便实例化自定义TestApplication

class MyTestRunner : AndroidJUnitRunner() {
    override fun newApplication(cl: ClassLoader?,classname: String?,context: Context?): Application {
        return super.newApplication(cl,TestApplication::class.java.name,context)
    }
}

TestApplication类。我已经验证了调用测试时该测试类是否已初始化

class TestApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        startKoin {
            androidLogger()
            androidContext(this@TestApplication)
            modules(emptyList())
        }
    }
}

这是我的实际androidTest。通过NoBeanDefFoundException

开始活动后,此操作将失败
  

未找到“ com.abhishek.mvvmdemo.onboarding.LoginViewModel”的定义。

@RunWith(AndroidJUnit4::class)
@LargeTest
class LoginactivityTest : KoinTest {
    private lateinit var loginViewModel: LoginViewModel

    @get:Rule
    val activityRule = activityTestRule(Loginactivity::class.java)

    @Before
    fun beforeTest() {
        loginViewModel = declareMock()
        loadKoinmodules(
            module {
//                single { ApiModule.providesApiService() }
                viewModel { loginViewModel }
            }
        )
    }

    @Test
    fun testProgress() {
        activityRule.launchactivity(null)
        onView(withId(R.id.emailEt))
            .perform(Viewactions.typeText("abhishek"))
    }

    @After
    fun afterTest() {
        stopKoin()
    }
}

我尝试了很多排列和组合,但是没有运气。我的gradle中也碰巧有以下配置


testOptions {
        animationsDisabled = true
    }

    packagingOptions {
        pickFirst 'mockito-extensions/org.mockito.plugins.MockMaker'
    }

testInstrumentationRunner "com.abhishek.mvvmdemo.MyTestRunner"

TL; DR

这里是github sample,再现了问题

alan0633 回答:带有Mock ViewModel的NoBeanDefFoundException,使用Koin,Espresso进行测试

这里发生的是ActivityTestRule在您的@Before方法之前启动了活动,因此模拟没有机会被初始化。

来自官方How to set Allow Mock Location on Android Device before executing AndroidTest with uiautomator and espresso?

  

此规则提供单个活动的功能测试。什么时候   在构造函数中将launchActivity设置为true,在   测试将在每个用Test注释的测试之前和之前启动   用Before注释的方法,它将在   测试完成,并用After注释的方法已完成。

您应该使用此documentation

来指定您不想自动启动活动。
ActivityTestRule (Class<T> activityClass,boolean initialTouchMode,boolean launchActivity)

然后在测试方法中,您可以通过以下方式手动启动活动

activityRule.launchActivity(null)

此外,您可能想签出constructor进行嘲笑。您不必将类声明为open

本文链接:https://www.f2er.com/3153086.html

大家都在问