gpt4 book ai didi

Android 单元测试数据存储

转载 作者:行者123 更新时间:2023-12-05 00:03:43 25 4
gpt4 key购买 nike

我正在尝试为我的 View 模型编写一个从数据存储中获取数据的测试,但我无法弄清楚。这是我的数据存储实现。当用户注册或登录时,我会保存用户数据,例如电子邮件和 token :

    class FlowAuthenticationDataStore(context: Context) : AuthenticationDataStore {
private val dataStore = context.createDataStore(name = "user_auth")
private val userEmailKey = preferencesKey<String>(name = "USER_EMAIL")
private val userTokenKey = preferencesKey<String>(name = "USER_TOKEN")
private val userNameKey = preferencesKey<String>(name = "USER_NAME")
private val userIsLoginKey = preferencesKey<Boolean>(name = "USER_IS_LOGIN")

override suspend fun updateUser(userDataStore: UserDataStoreModel) {
dataStore.edit {
it[userEmailKey] = userDataStore.email
it[userTokenKey] = userDataStore.token
it[userNameKey] = userDataStore.name
it[userIsLoginKey] = userDataStore.isLogin
}
}

override fun observeUser(): Flow<UserDataStoreModel> {
return dataStore.data.catch {
if (it is IOException) {
emit(emptyPreferences())
} else {
throw it
}
}.map {
UserDataStoreModel(
it[userIsLoginKey]!!,
it[userNameKey]!!,
it[userEmailKey]!!,
it[userTokenKey]!!
)
}
}
}
这是我的 View 模型。我观察用户数据存储,如果它成功并且有数据,那么我会更新我的实时数据。如果没有数据并且用户是第一次注册,那么我的实时数据等于数据类的默认值:
    class SplashScreenViewModel(
private val flowOnBoardingDataStore: FlowAuthenticationDataStore,
private val contextProvider: CoroutineContextProvider,
) :
ViewModel() {
private val _submitState = MutableLiveData<UserDataStoreModel>()
val submitState: LiveData<UserDataStoreModel> = _submitState

fun checkUserLogin() {
viewModelScope.launch {
kotlin.runCatching {
withContext(contextProvider.io) {
flowOnBoardingDataStore.observeUser().collect {
_submitState.value = it
}
}
}.onFailure {
_submitState.value = UserDataStoreModel()
}
}

}
}
这是我的测试课:
    @ExperimentalCoroutinesApi
class SplashScreenViewModelTest {
private val dispatcher = TestCoroutineDispatcher()

@get:Rule
val rule = InstantTaskExecutorRule()

@get:Rule
val coroutineTestRule = CoroutineTestRule(dispatcher)

@RelaxedMockK
lateinit var flowOnBoardingDataStore: FlowAuthenticationDataStore

private fun createViewModel()=SplashScreenViewModel(flowOnBoardingDataStore,
CoroutineContextProvider(dispatcher,dispatcher)
)

@Before
fun setup() {
MockKAnnotations.init(this)
}

@After
fun tearDown() {
unmockkAll()
}

@Test
fun `when user is already sign in, then state should return model`()=dispatcher.runBlockingTest {
val viewModel=createViewModel()
val userDataStoreModel= UserDataStoreModel(true,"test","test","test")
flowOnBoardingDataStore.updateUser(userDataStoreModel)
viewModel.checkUserLogin()
assertEquals(userDataStoreModel,viewModel.submitState.value)
}
}
这是我的测试功能的结果:
    junit.framework.AssertionFailedError: 
Expected :UserDataStoreModel(isLogin=true, name=test, email=test, token=test)
Actual :null

最佳答案

我找到了解决方案,并在此处发布以防万一有人需要它。
解决方案是使用 coEvery使用 flowOf 返回虚假数据从用例(您不需要使用 flowOf ,它基于您从用例返回的数据,在我的情况下它返回一个 flow ):

     @Test
fun `when user is already sign in, then state should return user data`()=dispatcher.runBlockingTest {
val userData=UserDataStoreModel(true, Name,
Email,"","")
coEvery { authenticationDataStore.observeUser() }returns flowOf(userData)
val viewModel=createViewModel()
viewModel.checkUserLogin()
assertEquals(userData,viewModel.submitState.value)
}
这是完整的测试类:
    @ExperimentalCoroutinesApi
class SplashScreenViewModelTest {
private val dispatcher = TestCoroutineDispatcher()

@get:Rule
val rule = InstantTaskExecutorRule()

@get:Rule
val coroutineTestRule = CoroutineTestRule(dispatcher)

@RelaxedMockK
lateinit var authenticationDataStore: AuthenticationDataStore

private fun createViewModel()=SplashScreenViewModel(authenticationDataStore,
CoroutineContextProvider(dispatcher,dispatcher)
)

@Before
fun setup() {
MockKAnnotations.init(this)
}

@After
fun tearDown() {
unmockkAll()
}

@Test
fun `when user is already sign in, then state should return user data`()=dispatcher.runBlockingTest {
val userData=UserDataStoreModel(true, Name,
Email,"","")
coEvery { authenticationDataStore.observeUser() }returns flowOf(userData)
val viewModel=createViewModel()
viewModel.checkUserLogin()
assertEquals(userData,viewModel.submitState.value)
}
}

关于Android 单元测试数据存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65856930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com