【问题标题】:How do I invoke a callback in a unit test in Android?如何在 Android 的单元测试中调用回调?
【发布时间】:2022-11-24 07:35:26
【问题描述】:

我想调用一个回调来断言它所做的执行。

我在我的应用程序中使用 MVVM。在我实现的其中一个视图模型中,我想确保 ui 状态在流程完成时发生变化。

在我的HomeViewModel.kt 我有:

@HiltViewModel
class HomeViewModel
@Inject
constructor(
    private val storageRepository: StorageRepository,
    private val accountRepository: AccountRepository,
) : ViewModel() {
// First state of isLoading is true
var uiState = mutableStateOf(HomeUiState())

...

fun addListener() {
    viewModelScope.launch {
        storageRepository.addListener(
            accountRepository.getUserId(),
            ::onDocumentEvent,
            onComplete = { 
                uiState.value = uiState.value.copy(isLoading = false) 
            },
            onError = { 
                error -> onAddListenerFailure(error) 
            }
        )
    }
}

我想写测试:

鉴于homeViewModel.addListener()

什么时候storageRepository.addListener(...) 完成

然后uiState.isLoading 为假

我已经搜索了一段时间,发现有些人提到使用 mockito 中的捕获器,但没有任何内容适用于我的情况。

这就是我现在所拥有的

@Test
fun `loading state is false when listener completes its process`() {
    val homeViewModel = HomeViewModel(storageRepository, accountRepository, logRepository)

    whenever(storageRepository.addListener(anyString(), any(), callbackCaptor.capture(), any()))
        .thenAnswer { callbackCaptor.value.invoke() }

    homeViewModel.addListener()

    // wait for mutable state to update
    dispatcher.scheduler.advanceUntilIdle()

    assertFalse(homeViewModel.uiState.value.isLoading)
}

其中callbackCaptor@Captor lateinit var callbackCaptor: ArgumentCaptor<() -> Unit>

我越来越

callbackCaptor.capture() must not be null

当然,我很乐意听到使用俘虏以外的其他东西的解决方案。

【问题讨论】:

    标签: android unit-testing kotlin mockito viewmodel


    【解决方案1】:

    我认为您没有初始化捕获器,请尝试以下操作

    @Test
    fun `loading state is false when listener completes its process`() {
        val homeViewModel = HomeViewModel(storageRepository, accountRepository, logRepository)
    
    val callbackCaptor = argumentCaptor<() -> Unit>() //used kotlin mockito
    
        whenever(storageRepository.addListener(anyString(), any(), callbackCaptor.capture(), any()))
            .thenAnswer { callbackCaptor.firstValue.invoke() } 
    
        homeViewModel.addListener()
    
        // wait for mutable state to update
        dispatcher.scheduler.advanceUntilIdle()
    
        assertFalse(homeViewModel.uiState.value.isLoading)
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-09
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 2018-01-20
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-12-16
      相关资源
      最近更新 更多