测试 Realm 中的平等 [英] Testing for equality in Realm

查看:30
本文介绍了测试 Realm 中的平等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在单元测试中测试 Realm 对象之间的相等性.但是,我无法让对象返回 true 以保证它们的相等性.

根据这里的领域文档,我应该能够做到这一点:

let expectedUser = User()expectedUser.email = "help@realm.io"XCTAssertEqual(testRealm.objects(User.self).first!,预期用户,用户未从服务器正确更新.")

但是,我使用以下代码得到以下测试失败:

领域模型

class Blurb: Object {动态变量文本 = ""}

测试

func testRealmEquality() {让 a = Blurb()a.text = "asdf"让 b = Blurb()b.text = "asdf"XCTAssertEqual(a, b)}

<块引用>

XCTAssertEqual 失败:(可选(模糊 {
text = asdf;
})") 不等于 ("Optional(Blurb {
text = asdf;
})")

解决方案

来自 Realm 的 Katsumi 在这里.Realm 对象的Equatable 实现如下:

BOOL RLMObjectBaseAreEqual(RLMObjectBase *o1, RLMObjectBase *o2) {//如果不是正确的类型,则抛出if ((o1 && ![o1 isKindOfClass:RLMObjectBase.class]) || (o2 && ![o2 isKindOfClass:RLMObjectBase.class])) {@throw RLMException(@"只能比较RLMObjectBase类的对象");}//如果相同的对象(或两者都是 nil)如果(o1 == o2){返回是;}//如果一个是 nilif (o1 == nil || o2 == nil) {返回否;}//如果不在领域或不同领域if (o1->_realm == nil || o1->_realm != o2->_realm) {返回否;}//如果其中一个是分离的如果 (!o1->_row.is_attached() || !o2->_row.is_attached()) {返回否;}//如果表和索引相同返回 o1->_row.get_table() == o2->_row.get_table()&&o1->_row.get_index() == o2->_row.get_index();}

总而言之,a) 如果两个对象都是非托管对象,它的工作方式与普通对象的 Equatable 相同.b) 如果两个对象都被管理,如果它们是同一个表(类)和索引,它们是相等的.c) 一个是托管的,另一个是非托管的,它们不相等.

托管"表示对象已存储在 Realm 中.

所以 ab 在你的代码中是不相等的.因为 ab 是非托管的(没有存储在 Realm 中)并且它们是不同的对象.

让 a = Blurb()a.text = "asdf"让 b = Blurb()b.text = "asdf"XCTAssertEqual(a.text, b.text)

此外,在测试相等性时,Realm 并不关心对象的值.Realm 仅检查表和行索引(如b)"所述.因为在数据库中存储具有相同值的不同对象是正常的.

两个对象相等的例子如下:

让 a = Blurb()a.text = "asdf"让领域=尝试!领域()尝试!领域.写{领域.add(a)}让 b = realm.objects(Blurb.self).first!打印(a == b)//真

I'm trying to test for equality among Realm objects in unit tests. However, I'm unable to get objects to return true for their equality.

According to the Realm docs here, I should be able to do that:

let expectedUser = User()
expectedUser.email = "help@realm.io"
XCTAssertEqual(testRealm.objects(User.self).first!,
               expectedUser,
               "User was not properly updated from server.")

However, I get the following test failure with the following code:

Realm Model

class Blurb: Object {
    dynamic var text = ""
}

Test

func testRealmEquality() {
    let a = Blurb()
    a.text = "asdf"
    let b = Blurb()
    b.text = "asdf"
    XCTAssertEqual(a, b)
}

XCTAssertEqual failed: ("Optional(Blurb {
text = asdf;
})") is not equal to ("Optional(Blurb {
text = asdf;
})")

解决方案

Katsumi from Realm here. Realm object's Equatable is implemented as follows:

BOOL RLMObjectBaseAreEqual(RLMObjectBase *o1, RLMObjectBase *o2) {
    // if not the correct types throw
    if ((o1 && ![o1 isKindOfClass:RLMObjectBase.class]) || (o2 && ![o2 isKindOfClass:RLMObjectBase.class])) {
        @throw RLMException(@"Can only compare objects of class RLMObjectBase");
    }
    // if identical object (or both are nil)
    if (o1 == o2) {
        return YES;
    }
    // if one is nil
    if (o1 == nil || o2 == nil) {
        return NO;
    }
    // if not in realm or differing realms
    if (o1->_realm == nil || o1->_realm != o2->_realm) {
        return NO;
    }
    // if either are detached
    if (!o1->_row.is_attached() || !o2->_row.is_attached()) {
        return NO;
    }
    // if table and index are the same
    return o1->_row.get_table() == o2->_row.get_table()
        && o1->_row.get_index() == o2->_row.get_index();
}

In summary, a) if both objects are unmanaged, it works same as normal object's Equatable. b) if both objects are managed, if they are the same table (class) and index, they are equal. c) If one is managed, another is unmanaged, ther are not equal.

"managed" means the object has stored in Realm.

So a and b in your code is not equal. Because a and b are unmanaged (have not stored in Realm) and they are different objects.

let a = Blurb()
a.text = "asdf"
let b = Blurb()
b.text = "asdf"
XCTAssertEqual(a.text, b.text)

Furthermore, when testing the equality, Realm doesn't care the values of the objects. Realm checks only a table and row index (as mentioned "b)"). Because different objects that has the same value are stored in the database is normal.

An example that two objects are equal is like the following:

let a = Blurb()
a.text = "asdf"

let realm = try! Realm()
try! realm.write {
    realm.add(a)
}

let b = realm.objects(Blurb.self).first!
print(a == b) // true

这篇关于测试 Realm 中的平等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆