首页 > 解决方案 > 单元测试通过比较 mockk 对象失败

问题描述

我已经实现了一个这样的Repository类:

class Repository @Inject constructor(private val dao: Dao) {

val response: LiveData<List<MyObject>> = dao.getAllObjects()
...
}

现在我为这样的代码和平编写了一个简单的单元测试:

class RepositoryTest {

@MockK
private lateinit var mockLiveData: LiveData<List<MyObject>>

@MockK
private lateinit var mockDao: Dao

@InjectMockKs
private lateinit var repository: Repository

init {
    MockKAnnotations.init(this, relaxed = true)
}

@Test
fun `Verify my objects are loaded from the database`() {
    // arrange
    every { dao.getAllObjects() } returns mockLiveData
    // assert
    verify { dao.getAllObjects() }
    assertEquals(this.mockLiveData, repository.response)
}

assertEquals检查失败并出现错误:

Expected :LiveData(mockLiveData#2)
Actual   :LiveData(child of mockDao#5#7)

我不明白为什么对象不相等,如何重写此测试以验证 livedata 对象是否相等?

标签: androidunit-testingjunitandroid-livedatamockk

解决方案


问题的原因是设置顺序。查看您的样品,订单是:

  1. 将模拟注入您的测试套件
  2. 使用注入的模拟创建存储库
  3. 在单个测试级别绑定 dao 方法,结果形式为mockLiveData
  4. 期望在存储库字段中有正确的 liveData

正如您在第 2 步中通过使用注释可以注意到的那样,您已经将 dao 与存储库绑定,并且默认dao.getAllObjects返回一些模拟(mockDao 的子级)。这就是断言失败的原因。

您的问题的解决方案是停止使用注释@InjectMockks 并初始化存储库惰性。

...
private val repository by lazy {
   Repository(dao)
}

@Test
fun `Verify my objects are loaded from the database`() {
    every { dao.getAllObjects() } returns mockLiveData
    assertEquals(this.mockLiveData, repository.response)
}

干杯


推荐阅读