swift 测试Realm中的相等性

3phpmpom  于 2023-04-28  发布在  Swift
关注(0)|答案(2)|浏览(214)

我试图在单元测试中测试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.")

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

领域模型

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

测试

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

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

yfjy0ee7

yfjy0ee71#

我是 Realm 的胜美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();
}

总之,a)如果两个对象都是非托管的,它的工作方式与普通对象的Equatable相同。B)如果两个对象都被管理,如果它们是相同的表(类)和索引,则它们相等。c)如果一个是管理的,另一个是非管理的,它们不相等。
“managed”表示对象已存储在Realm中。
所以代码中的ab不相等。因为ab是非托管的(没有存储在Realm中),它们是不同的对象。

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

此外,在测试相等性时,Realm不关心对象的值。Realm仅检查表和行索引(如所述“b”)。因为不同的对象具有相同的值存储在数据库中是正常的。
2023 Edit -以下仅在对象具有主键时为真,因此Blurb对象需要定义为

class Blurb: Object {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var text = ""
}

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

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
hl0ma9xz

hl0ma9xz2#

你知道比较协议在iOS上是如何工作的吗?
如果没有,请在此处查看http://nshipster.com/swift-comparison-protocols/
基本上如果你做了

let a = NSObject()
let b = NSObject()
let c = a
a == b // false
a == c // true

你应该创建一个这样的类,它符合Equatable

class MyClass: Equatable {
  let myProperty: String

  init(s: String) {
    myProperty = s
  }
}

func ==(lhs: MyClass, rhs: MyClass) -> Bool {
  return lhs.myProperty == rhs.myProperty
}

let myClass1 = MyClass(s: "Hello")
let myClass2 = MyClass(s: "Hello")
myClass1 == myClass2 // true
myClass1 != myClass2 // false
myClass1 === myClass2 // false
myClass1 !== myClass2 // true

我建议检查一下。测试文本

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

相关问题