【发布时间】:2021-04-10 23:11:33
【问题描述】:
我正在为我的 ViewModel 编写单元测试。我已经模拟了我的数据源,并想测试该数据源返回成功和错误情况。如果我单独运行测试一切正常。
在第一个方法中我模拟返回成功,在第二个方法中我模拟返回错误。当我一起运行这两个测试时(通过单击类名中的运行测试),在第二种方法中,我希望 dataSource.getPackageCard() 返回 ResponseState.Error("error1337") 但是它返回 ResponseState.Success(responseDto)。换句话说,它会记住第一种方法的模拟值。为什么 ?如何解决这个问题?
@MediumTest
@RunWith(AndroidJUnit4::class)
@ExperimentalCoroutinesApi
class MyViewModelTest {
@get: Rule
var instantExecutorRule = InstantTaskExecutorRule()
@get: Rule
var mainCoroutineRule = MainCoroutineRule()
private lateinit var viewModel: MyViewModel
lateinit var MyRepository: MyRepository
val responseDto = MyResponseDto().apply {
val myList = mutableListOf<CardListGroupDTO>()
myList.add(CardListGroupDTO(cardGroupType = "test",
headerTitle = "test",
buttonAll = ButtonDto(title = "test", url = "test")
))
groupList = myList
}
@MockK
lateinit var dataSource: MyDataSource
@Before
fun setup() {
MockKAnnotations.init(this)
MyRepository = MyRepositoryImpl.getInstance(dataSource)
viewModel = MyViewModel(MyRepository)
}
@After
fun afterTests() {
unmockkAll()
unmockkObject(dataSource)
}
@Test
fun `test successful case`() = runBlockingTest {
// given
coEvery {
dataSource.getPackageCard()
} returns ResponseState.Success(
responseDto
)
var counter = 0
viewModel.MyResponseDto.observeForever(
object : Observer<ResponseState<MyResponseDto>> {
override fun onChanged(t: ResponseState<MyResponseDto>) {
// println(viewModel.MyResponseDto.value)
when (counter) {
0 ->
Truth.assertThat(t).isEqualTo(ResponseState.Loading(true))
1 ->
Truth.assertThat(t).isEqualTo(ResponseState.Success(responseDto))
2 -> {
Truth.assertThat(t).isEqualTo(ResponseState.Loading(false))
viewModel.MyResponseDto.removeObserver(this)
}
}
counter++
}
})
viewModel.getPackageCard()
}
@Test
fun `test error case`() = runBlockingTest {
val errorMessage = "error1337"
// given
coEvery {
dataSource.getPackageCard()
} returns ResponseState.Error(
errorMessage
)
var counter = 0
viewModel.MyResponseDto.observeForever(
object : Observer<ResponseState<MyResponseDto>> {
override fun onChanged(t: ResponseState<MyResponseDto>) {
// println(viewModel.MyResponseDto.value)
when (counter) {
0 ->
Truth.assertThat(t).isEqualTo(ResponseState.Loading(true))
1 ->
Truth.assertThat(t).isEqualTo(ResponseState.Error(errorMessage))
2 -> {
Truth.assertThat(t).isEqualTo(ResponseState.Loading(false))
viewModel.MyResponseDto.removeObserver(this)
}
}
counter++
}
})
viewModel.getPackageCard()
}
}
【问题讨论】:
标签: android unit-testing kotlin testing mocking