2016-08-10 10 views
3

ユニットテストでオブジェクトRealmの間の等価性をテストしようとしています。しかし、私はオブジェクトが同等のために返すようにtrueを返すことができません。レルム内の等価性のテスト

Realm docs hereによると、私はそれを行うことができるはずですが:

let expectedUser = User() 
expectedUser.email = "[email protected]" 
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に失敗しました:( "オプション(宣伝文{
テキスト= ASDF。
})はオプション(宣伝文{
テキスト=空自 ")(等しくない";?

答えて

7

をテストするための.textチェックすることをお勧めします。

要約
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と同じように動作します:次のようにレルムオブジェクトのEquatableが実装されています。 b)両方のオブジェクトが管理されている場合、それらが同じ表(クラス)および索引である場合、それらは等しい。 c)1つが管理されている場合、別のものが管理されていない場合、それらは等しくない。

「管理対象」は、オブジェクトがレルムに格納されていることを意味します。

したがってabは同じではありません。 abは管理されていない(レルムに格納されていない)ため、異なるオブジェクトです。

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

さらに、等価性をテストする場合、レルムはオブジェクトの値には関係ありません。レルムは、表と行の索引のみをチェックします(前述の "b)")。同じ値を持つ異なるオブジェクトがデータベースに格納されているため、正常です。

2つのオブジェクトが等しいという例では、次のようなものです:

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 
+0

ありがとうございます。しかし、realm docsのコード例では、同じemailプロパティ値を持つアンマネージドオブジェクトは想定されていませんか?なぜそのテストは終わったのですか? – solidcell

+0

@solidcell混乱して申し訳ありません。私は文書が間違っていると思います。私はすぐに文書の問題を指摘のおかげで解決します! –

+0

クール、もう一度ありがとう! – solidcell

0

は、あなたが比較プロトコルは、iOSの上でどのように動作するか知っています
})」)

あなたの場合あなたは

let a = NSObject() 
let b = NSObject() 
let c = a 
a == b // false 
a == c // true 
をすれば、基本的にここで http://nshipster.com/swift-comparison-protocols/

をチェックしません。

あなたが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) 
} 
+0

いや、私はしかし、私は 'Realm'がそれを実装する方法がわからないよ、またなぜそのドキュメントがそれを示して、Equatable'がどのように動作するか'知っています明らかに同等のオブジェクトをテストするために使用することができます(同じ正確なオブジェクトではありません)。可能であれば、配列内のすべてのオブジェクトのすべてのプロパティをテストする必要はありません。それは手を抜く傾向があります。 – solidcell

+0

最後の提案。これについてRealmのドキュメントをチェックしましたか? https://realm.io/docs/swift/latest/#testing –

+0

さて、私の質問の始まりを見て、私はドキュメントにリンクし、関連するスニペットを貼り付けていることがわかります。 – solidcell