JUnit测试Firebase实时数据库DataSnapshot与mockk

huangapple go评论63阅读模式
英文:

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&lt;GETUsers&gt; =
    try {
        val users = databaseReference.get().await().getValue&lt;GETUsers&gt;()!!
        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 = &quot;exampleUser01ID&quot;
    val user02ID = &quot;exampleUser02ID&quot;
    val users = mutableMapOf(user01ID to user01, user02ID to user02)
    val expectedResult = GETUsers(users)
    val task: Task&lt;DataSnapshot&gt; = mockkTask()
    val snapshot: DataSnapshot = mockk()

    every { databaseReference.get() } returns task
    every { task.result } returns snapshot
    every { snapshot.getValue&lt;GETUsers&gt;()!! } 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 &lt;reified T&gt; mockkTask(exception: Exception? = null): Task&lt;T&gt; {
    val task = mockk&lt;Task&lt;T&gt;&gt;(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 &#39;bootstrap&#39;; com.example.social_bike_repair.models.GETUsers is in unnamed module of loader &#39;app&#39;))

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&lt;GETUsers&gt;()!!

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&lt;GETUsers&gt;()!! } returns expectedResult

to this

every { snapshot.getValue(GETUsers::class.java) } returns expectedResult

huangapple
  • 本文由 发表于 2023年7月10日 23:51:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76655397.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定