You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Mockk模拟密封类并验证BottomNavigate的参数类型?

测试ViewModel中密封类Action的调用情况

假设你的ViewModel通过Flow(或LiveData)暴露MyActions事件,比如:

class MyViewModel : ViewModel() {
    private val _actions = MutableSharedFlow<MyActions>()
    val actions = _actions.asSharedFlow()

    fun triggerBottomNavigate() {
        viewModelScope.launch {
            _actions.emit(MyActions.BottomNavigate(Fragment2()))
        }
    }
}

下面是用Mockk结合协程测试框架的两种测试方案:

方案1:直接收集事件并断言

通过收集流中的事件,直接验证类型和参数:

@OptIn(ExperimentalCoroutinesApi::class)
class MyViewModelTest {
    private val testDispatcher = StandardTestDispatcher()

    @Before
    fun setup() {
        Dispatchers.setMain(testDispatcher)
    }

    @After
    fun tearDown() {
        Dispatchers.resetMain()
    }

    @Test
    fun `triggerBottomNavigate emits BottomNavigate with Fragment2`() = runTest {
        val viewModel = MyViewModel()
        val collectedActions = mutableListOf<MyActions>()

        // 启动事件收集
        viewModel.actions.collect { collectedActions.add(it) }

        // 触发目标方法
        viewModel.triggerBottomNavigate()
        advanceUntilIdle() // 等待协程执行完成

        // 验证事件类型
        val emittedAction = collectedActions.first()
        check(emittedAction is MyActions.BottomNavigate) { "Expected BottomNavigate action" }
        // 验证参数类型
        check(emittedAction.fragment is Fragment2) { "Expected Fragment2 as parameter" }
    }
}

方案2:用Mockk验证收集器的调用

创建一个Mock的事件收集器,通过verify检查是否收到符合要求的Action:

@OptIn(ExperimentalCoroutinesApi::class)
class MyViewModelTest {
    private val testDispatcher = StandardTestDispatcher()

    @Before
    fun setup() {
        Dispatchers.setMain(testDispatcher)
    }

    @After
    fun tearDown() {
        Dispatchers.resetMain()
    }

    @Test
    fun `triggerBottomNavigate calls collector with valid BottomNavigate`() = runTest {
        val viewModel = MyViewModel()
        // 创建宽松的mock收集器
        val mockCollector = mockk<(MyActions) -> Unit>(relaxed = true)

        // 启动收集
        launch(testDispatcher) {
            viewModel.actions.collect(mockCollector)
        }

        viewModel.triggerBottomNavigate()
        advanceUntilIdle()

        // 验证mock被调用,且参数符合条件
        verify {
            mockCollector.invoke(
                match { action ->
                    action is MyActions.BottomNavigate && action.fragment is Fragment2
                }
            )
        }
    }
}

注意事项

  • 确保依赖中引入mockk和kotlinx-coroutines-test库
  • 如果用LiveData替代Flow,可改用TestObserver或observeForever来收集事件,断言逻辑类似

内容的提问来源于stack exchange,提问作者wamae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:40:32