繁体   English   中英

Koin-如何为咖啡测试提供模拟ViewModel?

[英]Koin - how to provide mock ViewModel for espresso test?

我们如何将模拟的viewModel注入到Activity中以进行浓缩咖啡测试? 使用declareMock我在Test类中获得了模拟对象,但Activity接收了常规的viewModel对象。

@RunWith(AndroidJUnit4::class)
class SomeActivityTest : KoinTest {
    @Rule
    @JvmField
    val rule = ActivityTestRule(SomeActivity::class.java, true, true)
    val viewModel: MyViewModel by inject()

    @Before
    fun setup() {
        declareMock<MyViewModel>(isFactory = true, binds = listOf(ViewModel::class))
    }

    @After
    fun cleanUp() {
        stopKoin()
    }

    @Test
    fun shouldHaveTextViewVisible() {
        `when`(viewModel.sayHello())
                .thenReturn("hello view-model")
        onView(withId(R.id.tv_homescreen_message))
                .check(matches(isDisplayed()))
        onView(withId(R.id.tv_homescreen_message))
                .check(matches(withText("hello view-model")))
    }
}

在这种情况下,Espresso测试仍在使用主应用程序类,该类声明了应用程序所需的所有koin模块。

koin没有任何模块的情况下启动koin ,允许我们在测试期间仅加载所需的模块。

// application class for espresso tests
class TestApp : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin(this, emptyList())
    }
}

class TestAppJUnitRunner : AndroidJUnitRunner() {
    override fun newApplication(cl: ClassLoader?, className: String?, context: Context?): Application {
        return super.newApplication(cl, TestApp::class.java.name, context)
    }
}

// app module build.gradle
android {
    defaultConfig {
        testInstrumentationRunner "com.package.TestAppJUnitRunner"
    }
}

在开始活动之前声明模拟方法很重要

@RunWith(AndroidJUnit4::class)
class SomeActivityTest : KoinTest {
    @Rule
    @JvmField
    val rule = ActivityTestRule(SomeActivity::class.java, true, false)

    lateinit var mockVm: MyViewModel


    @Before
    fun setup() {
        mockVm = mock(MyViewModel::class.java)

        loadKoinModules(module {
            viewModel {
                mockVm
            }
        })
    }

    @After
    fun cleanUp() {
        stopKoin()
    }

    @Test
    fun shouldHaveTextViewWithMessage() {
        // 1. declare mock method
        val message = "hello view-model"
        Mockito.`when`(mockVm.sayHello())
                .thenReturn(message)

        // 2. start activity
        rule.launchActivity(null)


        // 3. test
        onView(withId(R.id.tv_message))
                .check(matches(isDisplayed()))

        onView(withId(R.id.tv_message))
                .check(matches(withText(message)))
    }
}

样例代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM