这是我的用例代码界面 -
interface ItemUseCase {
fun performItemAction(action: ItemAction): LiveData<Result>
}
这是实现 -
class ItemUseCaseImpl(
private val dataRepository: DataRepository
) : ItemUseCase {
override fun performItemAction(action: ItemAction) = liveData {
emit(Result.Loading)
emit(dataRepository.performDataAction(action))
}
}
我是编写单元测试的新手。所以我需要帮助 -
1)我可以在我的用例中测试什么
2)我还尝试在下面编写一些单元测试,但是如何将 LiveData 放入 thenReturn
这是我的单元测试代码 -
class ItemUseCaseImplTest {
@Rule
@JvmField
val rule = InstantTaskExecutorRule()
@Mock
private lateinit var itemUseCase: ItemUseCase
@Mock
private lateinit var dataRepository: DataRepository
@Before
fun setUp() {
dataRepository = mockk()
itemUseCase = ItemUseCaseImpl(dataRepository)
}
@After
fun tearDown() {
}
@Test
fun performItemAction() {
runBlocking {
whenever(
itemUseCase.performItemAction(
ItemAction.RegisterUser(“xyz”, "20")
)
)
.thenReturn(???)
}
}
}
最佳答案
这是示例代码。
我的存储库
interface RepositoryInterface {
suspend fun performAPI(): Result<Map<String, Top100Item>>
}
class Repository(private val service: GameService) : RepositoryInterface {
override suspend fun performAPI(): Result<Map<String, Top100Item>> = try {
Result.Success(service.getTop100())
} catch (exception: Exception) {
Result.Error(null, exception)
}
}
我的MainViewModel
是从ViewModel扩展并实现GameUserInterface
interface GameUserCase {
fun getGames(): LiveData<Result<Map<String, Top100Item>>>
}
class MainViewModel(
private val repository: RepositoryInterface,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO,
private val loadingResource: Result<Map<String, Top100Item>> = Result.Loading(null)
) : ViewModel(), GameUserCase {
override fun getGames(): LiveData<Result<Map<String, Top100Item>>> = liveData(dispatcher) {
emit(loadingResource)
emit(repository.performAPI())
}
}
这是测试 MainViewModel 的测试示例:
@ExperimentalCoroutinesApi
@RunWith(MockitoJUnitRunner::class)
class MainViewModelTest {
@Mock
private lateinit var repository: RepositoryInterface
private lateinit var viewModel: MainViewModel
private val testDispatcher = TestCoroutineDispatcher()
@ExperimentalCoroutinesApi
@get:Rule
var coroutinesTestRule = CoroutinesTestRule()
@Rule
@JvmField
var rule: TestRule = InstantTaskExecutorRule()
private val loading: Result.Loading<Map<String, Top100Item>> = Result.Loading(null)
private val mockItem = Top100Item(appId = 30, name = "name", developer = "developer", publisher = "publisher")
@Before
fun setup() {
viewModel = MainViewModel(repository, testDispatcher, loading)
}
@Test
fun testGetDataSuccess() {
testDispatcher.pauseDispatcher()
val map = mapOf("30" to mockItem)
val successResult = Result.Success(map)
runBlockingTest {
`when`(repository.performAPI()).thenReturn(successResult)
val result = viewModel.getGames()
testDispatcher.resumeDispatcher()
// verify loading
assertThat(result.getOrAwaitValue()).isEqualTo(loading)
result.observeForTesting {
testDispatcher.resumeDispatcher()
assertThat(result.value).isEqualTo(successResult)
}
}
}
}
在测试类中,我将在调用 getGames
时验证响应是否成功,以便数据将以 Result.Success
进行响应。对于 getOrAwaitValue
和 observeForTesting
方法,您可以从 architecture-components-samples 检查
协程测试规则来自 here
关于Android 用例单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59512736/