我有一个相当简单的 save()
方法来保存 RealmModel
,在保存 realm.close()
之后调用,因为数据库不再需要。
问题:尽管使用 mockito 模拟了 Realm,但调用了实际的 close()
方法。这会导致异常:
IllegalStateException: Realm access from incorrect thread. Realm instance can only be closed on the thread it was created.
mockito 不能模拟 Realm 吗?我不想为了测试这个案例而包含 PowerMock :D
使用 realm-gradle-plugin
5.0.0 测试
测试类
import io.realm.Realm
import io.realm.RealmModel
class TestedClass {
fun save(realm: Realm, objectToBeSaved: RealmModel) {
// Persist your data in a transaction
realm.executeTransaction {
// Using executeTransaction with a lambda reduces code size
// and makes it impossible to forget to commit the transaction.
it.copyToRealm(objectToBeSaved)
}
// Close database after saving (this causes the exception)
realm.close()
}
}
单元测试
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.verify
@Test
fun save() {
val testedClass = TestedClass()
val mockRealm: Realm = mock()
val objectToBeSaved: RealmModel = mock()
testedClass.save(mockRealm, objectToBeSaved) // this causes the exception
verify(mockRealm).executeTransaction(any())
verify(mockRealm).copyToRealm(objectToBeSaved)
verify(mockRealm).close()
}
最佳答案
解决方案是新的 Realm 版本。
似乎在 realm-gradle-plugin
5.0.0 和 5.3.1 之间的某处,这个问题在 Realm 库端得到了修复,即使我找不到关于 changelog 的任何文档提到它。
这就是我最终必须完全测试 TestedClass
通过单元测试
import com.nhaarman.mockito_kotlin.argumentCaptor
import com.nhaarman.mockito_kotlin.inOrder
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.verifyNoMoreInteractions
@Test
fun save() {
val testedClass = TestedClass()
val mockRealm: Realm = mock()
val objectToBeSaved: RealmModel = mock()
val captor = argumentCaptor<Realm.Transaction>()
testedClass.save(mockRealm, objectToBeSaved)
inOrder(mockRealm).apply {
verify(mockRealm).executeTransaction(captor.capture())
verify(mockRealm).close()
// Now make sure the lambda passed to executeTransaction() does the right thing
captor.firstValue.execute(mockRealm)
verify(mockRealm).copyToRealm(objectToBeSaved)
verifyNoMoreInteractions(mockRealm)
}
}
关于android - 尽管 Realm 被模拟,但实际的 close() 方法被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49667400/