在境界中测试平等

sol*_*ell 4 testing xcode realm ios swift

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

根据这里Realm文档,我应该能够这样做:

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

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

境界模型

class Blurb: Object {
    dynamic var text = ""
}
Run Code Online (Sandbox Code Playgroud)

测试

func testRealmEquality() {
    let a = Blurb()
    a.text = "asdf"
    let b = Blurb()
    b.text = "asdf"
    XCTAssertEqual(a, b)
}
Run Code Online (Sandbox Code Playgroud)

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

kis*_*umi 12

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

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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

let a = Blurb()
a.text = "asdf"
let b = Blurb()
b.text = "asdf"
XCTAssertEqual(a.text, b.text)
Run Code Online (Sandbox Code Playgroud)

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

两个对象相等的示例如下所示:

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
Run Code Online (Sandbox Code Playgroud)

  • 这种行为改变了吗?看起来至少从Realm 3.7.4起,“ Equatable”仅适用于具有主键的对象。当我在没有主键的类上尝试与上面类似的创建/添加/获取循环时,我会得到isSameObject(as :)返回true,而isEqual()返回false。 (2认同)