Android 用例单元测试

标签 android kotlin junit android-livedata kotlin-coroutines

这是我的用例代码界面 -

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 进行响应。对于 getOrAwaitValueobserveForTesting 方法,您可以从 architecture-components-samples 检查

协程测试规则来自 here

关于Android 用例单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59512736/

相关文章:

android - 从 SDcard 使用 XmlPullParser 进行解析

lambda - RXKotlin Lambda 理解

java - 创建 gradle 插件时将生成的 java 或 kotlin 源代码放在哪里?

Controller 休息服务的 Spring Junit 测试用例

Android在gridview中的不同布局

java - 离开 SettingsActivity 时应用强制关闭

kotlin - 使用反射调用具有默认参数值的函数

java - 尽管出现错误,如何继续循环中的测试

java - 我应该在单元测试时从正在测试的类中调用方法吗?

android - Android和Accont Kit:设置默认语言