首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Mockk创建观察者

如何使用Mockk创建观察者
EN

Stack Overflow用户
提问于 2021-09-08 20:23:17
回答 1查看 434关注 0票数 0

你好,我有一个使用Mockito的单元测试,我将其中的大部分转换为使用Mockk,除了我想要创建一个android生命周期观察者的部分

Mockito版本

代码语言:javascript
复制
@Mock
private lateinit var dataObserver: Observer<Result<List<Character>>> 

不工作的Mockk版本

代码语言:javascript
复制
private var dataObserver: Observer<Result<List<Character>>> = mockk(relaxed = true)

当我对上面的内容使用Mockk,当我使用Mockito版本时,我的测试用例失败了

错误信息

代码语言:javascript
复制
java.lang.AssertionError: Verification failed: call 1 of 1: Observer(#2).onChanged(eq(Success([Character(name=myName, img=image, occupation=[], status=status, nickname=nickName, appearance=[])])))) was not called

    at io.mockk.impl.recording.states.VerifyingState.failIfNotPassed(VerifyingState.kt:66)
    at io.mockk.impl.recording.states.VerifyingState.recordingDone(VerifyingState.kt:42)
    at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:60)
    at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
    at io.mockk.MockKDsl.internalCoVerify(API.kt:143)
    at io.mockk.MockKKt.coVerify(MockK.kt:175)
    at io.mockk.MockKKt.coVerify$default(MockK.kt:172)
    at com.example.breakingbad.MainActivityViewModelTest$fetchCharacters$1.invokeSuspend(MainActivityViewModelTest.kt:76)

全测试用例

代码语言:javascript
复制
package com.example.breakingbad

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.breakingbad.data.DataRepository
import com.example.breakingbad.model.Character
import com.example.breakingbad.viewModel.MainActivityViewModel
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.*
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner

//@RunWith(MockitoJUnitRunner::class)

@ExperimentalCoroutinesApi
class MainActivityViewModelTest {

    @get:Rule
    val instantTaskExecutorRule = InstantTaskExecutorRule()

    private val testDispatcher = TestCoroutineDispatcher()
    private val testCoroutineScope = TestCoroutineScope(testDispatcher)

    private val dataRepository: DataRepository = mockk(relaxed = true)

    private val mainActivityViewModel = MainActivityViewModel(dataRepository)

//    @Mock
//    private lateinit var dataObserver: Observer<Result<List<Character>>>

    private var dataObserver: Observer<Result<List<Character>>> = mockk(relaxed = true)

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

    @After
    fun cleanup() {
        Dispatchers.resetMain()
        testCoroutineScope.cleanupTestCoroutines()
    }

    @Test
    fun fetchCharacters() {
        testCoroutineScope.launch {

            coEvery { dataRepository.getCharacters() } returns Result.success(arrayListOf(Character(
                    name = "myName",
                    img = "image",
                    occupation = arrayListOf(),
                    status = "status",
                    nickname = "nickName",
                    appearance = arrayListOf()
            )))

            mainActivityViewModel.fetchCharacters()
            coVerify { dataRepository.getCharacters() }

            coVerify { dataObserver.onChanged(
                    Result.success(listOf(Character (
                            name = "myName",
                            img = "image",
                            occupation = arrayListOf(),
                            status = "status",
                            nickname = "nickName",
                            appearance = arrayListOf()
                    )))
            ) }
            mainActivityViewModel.charactersLiveData.removeObserver(dataObserver)
        }
    }
}

如何使用Mockk通过测试用例?我做错什么了?

编辑

ViewModel

代码语言:javascript
复制
class MainActivityViewModel @Inject constructor(
        private val dataRepository: DataRepository
): ViewModel() {
    private val _charactersLiveData = MutableLiveData<Result<ArrayList<Character>>>()
    val charactersLiveData: LiveData<Result<ArrayList<Character>>> = _charactersLiveData

    fun fetchCharacters() {
        viewModelScope.launch(Dispatchers.IO) {
            _charactersLiveData.postValue(dataRepository.getCharacters())
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2022-06-05 14:24:03

测试liveData的表单是捕获观察者传递的数据。

PD:在你的例子中,也许他忘了在livedata中添加observerForever。

无论如何,我留下一个例子:

代码语言:javascript
复制
private val dataObserver: Observer<Result<List<Character>>> = mockk()

private val argumentCaptor: CapturingSlot<Result<List<Character>> = slot()

@Test
fun fetchCharacters() = runBlockingTest {

    //Move to @Before    
    mainActivityViewModel.charactersLiveData.observerForever(dataObserver)
    
    coEvery { dataRepository.getCharacters() } returns Result.success(arrayListOf(Character(
        name = "myName",
        img = "image",
        occupation = arrayListOf(),
        status = "status",
        nickname = "nickName",
        appearance = arrayListOf()
    )))

    mainActivityViewModel.fetchCharacters()
    
    coVerify { dataRepository.getCharacters() }
    verify { dataObserver.onChanged(capture(argumentCaptor)) }

    with(argumentCaptor){

        //Here can be assert data, example:
        assert(this is Result.Success)
        assertEquals(YourData, this.data) //validation according to your data structure
    }

    //Move to @After
    mainActivityViewModel.charactersLiveData.removeObserver(dataObserver)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69109251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档