英文:
JUnit testing for Firebase Realtime Database DataSnapshot with mockk
问题
我尝试为从Firebase实时数据库加载数据的异步函数编写测试。
suspend fun getUsers(): Resource<GETUsers> =
try {
val users = databaseReference.get().await().getValue<GETUsers>()!!
Resource.Success(users)
} catch(e: Exception) {
Resource.Error(e.message ?: Constants.UNKNOWN_ERROR)
}
我已经为Firebase授权编写了类似的测试,这些测试起作用。然而,当前的测试未返回所期望的结果。
@Test
fun `调用getUsers()应返回成功,并包含两个用户`() {
val user01 = GETUser()
val user02 = GETUser()
val user01ID = "exampleUser01ID"
val user02ID = "exampleUser02ID"
val users = mutableMapOf(user01ID to user01, user02ID to user02)
val expectedResult = GETUsers(users)
val task: Task<DataSnapshot> = mockkTask()
val snapshot: DataSnapshot = mockk()
every { databaseReference.get() } returns task
every { task.result } returns snapshot
every { snapshot.getValue<GETUsers>()!! } returns expectedResult
val result = runBlocking { repository.getUsers() }
println(result)
Assert.assertTrue(result is Resource.Success)
Assert.assertEquals(2, (result as Resource.Success).data.users.size)
Assert.assertEquals(user01, result.data.users[user01ID])
Assert.assertEquals(user02, result.data.users[user02ID])
}
private inline fun <reified T> mockkTask(exception: Exception? = null): Task<T> {
val task = mockk<Task<T>>(relaxed = true) {
every { isComplete } returns true
every { this@mockk.exception } returns exception
every { isCanceled } returns false
every { result } returns mockk(relaxed = true)
}
return task
}
我认为错误是因为将GETUsers强制转换不正确,如果我打印结果,会显示以下内容:
Error(message=class java.lang.Object cannot be cast to class com.example.social_bike_repair.models.GETUsers (java.lang.Object is in module java.base of loader 'bootstrap'; com.example.social_bike_repair.models.GETUsers is in unnamed module of loader 'app'))
我认为我需要在mockkTast函数的这一行上进行一些更改,但我不太确定应该如何更改。
every { result } returns mockk(relaxed = true)
英文:
I try to write tests for async functions that load data from the Firebase Realtime Database.
suspend fun getUsers(): Resource<GETUsers> =
try {
val users = databaseReference.get().await().getValue<GETUsers>()!!
Resource.Success(users)
} catch(e: Exception) {
Resource.Error(e.message ?: Constants.UNKNOWN_ERROR)
}
I have already written similar tests for the Firebase authorizations which have worked. However, the current test does not return the desired result.
@Test
fun `getUsers() called should return success with two users`() {
val user01 = GETUser()
val user02 = GETUser()
val user01ID = "exampleUser01ID"
val user02ID = "exampleUser02ID"
val users = mutableMapOf(user01ID to user01, user02ID to user02)
val expectedResult = GETUsers(users)
val task: Task<DataSnapshot> = mockkTask()
val snapshot: DataSnapshot = mockk()
every { databaseReference.get() } returns task
every { task.result } returns snapshot
every { snapshot.getValue<GETUsers>()!! } returns expectedResult
val result = runBlocking { repository.getUsers() }
println(result)
Assert.assertTrue(result is Resource.Success)
Assert.assertEquals(2, (result as Resource.Success).data.users.size)
Assert.assertEquals(user01, result.data.users[user01ID])
Assert.assertEquals(user02, result.data.users[user02ID])
}
private inline fun <reified T> mockkTask(exception: Exception? = null): Task<T> {
val task = mockk<Task<T>>(relaxed = true) {
every { isComplete } returns true
every { this@mockk.exception } returns exception
every { isCanceled } returns false
every { result } returns mockk(relaxed = true)
}
return task
}
I think the error is because the cast to GETUsers does not work correctly, if I print result I get the following displayed:
Error(message=class java.lang.Object cannot be cast to class com.example.social_bike_repair.models.GETUsers (java.lang.Object is in module java.base of loader 'bootstrap'; com.example.social_bike_repair.models.GETUsers is in unnamed module of loader 'app'))
I think I need to change something on this line of the mockkTast function, but I'm not quite sure how.
every { result } returns mockk(relaxed = true)
答案1
得分: 0
问题是要测试的代码中的强制转换不正确。
我已经相应地修改了:
val users = databaseReference.get().await().getValue(GETUsers::class.java)!!
测试按预期工作。
另外,我必须更改这部分:
every { snapshot.getValue(GETUsers::class.java) } returns expectedResult
英文:
The problem was that the cast in the code to be tested was incorrect.
I have
val users = databaseReference.get().await().getValue<GETUsers>()!!
amended accordingly
val users = databaseReference.get().await().getValue(GETUsers::class.java)!!
and the test works as intended.
Also I must changed this
every { snapshot.getValue<GETUsers>()!! } returns expectedResult
to this
every { snapshot.getValue(GETUsers::class.java) } returns expectedResult
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论