2015-09-10 6 views
7

Angesichts der folgenden Swift Klasse:XCTAssertEqual arbeiten nicht für gleichzusetzen Typen in Swift

class TestObject: NSObject { 
    let a: Int 

    init(a: Int) { 
     self.a = a 
     super.init() 
    } 
} 

func ==(lhs: TestObject, rhs: TestObject) -> Bool { 
    return lhs.a == rhs.a 
} 

und ein Testfall dafür:

func testExample() { 
    let a = TestObject(a: 4) 
    let b = TestObject(a: 4) 

    XCTAssertEqual(a, b) // fails 

    let isEqual = a == b 
    XCTAssert(isEqual) // passes  
} 

die verschiedenen Werte Rückkehr zwei assert, aber sie sollten beide Pass .

Ich habe versucht, eine benutzerdefinierte Funktion assert schreiben:

func BAAssertEquatable<A: Equatable>(x1: A, _ x2: A, _ message: String, file: String = __FILE__, line: UInt = __LINE__) { 
    let operandsEqual = (x1 == x2) 
    XCTAssert(operandsEqual, message, file: file, line: line) 
} 

aber dies nicht gelingt auch:

BAAssertEquatable(a, b, "custom assert") // fails 

Was hier los?

+0

+1 für die sehr gute Analyse. Leider kann ich das Problem nur erraten und weitere Analysen empfehlen. Für mich sieht es so aus, als ob swift irgendwo die Information verliert, dass Ihr 'TestObject' das Equatable Protocol implementiert. Könnten Sie Ihrem Operator func einen 'Ausdruck' hinzufügen? Ich erwarte, dass es in den betreffenden Fällen nicht aufgerufen wird. Außerdem würde ich ein "override" irgendwie vor "func ==" erwarten. Tut mir leid, dass ich im Moment nicht besser helfen kann. – jboi

+0

@jboi Sie haben Recht - der Operator == wird nur einmal aufgerufen (im direkten Aufruf von testExample), aber er sollte dreimal aufgerufen werden. Ich kann das Schlüsselwort override nicht auf der obersten Ebene verwenden (es handelt sich um einen Syntaxfehler). – Bill

+0

Ich denke, das ist mit dem Bug/Problem hier verbunden: http://StackOverflow.com/Questions/31099379/Bug-with-Equals-Operator-and-NOsobjects-in-Swift-2-0 – Bill

Antwort

3

Anrufe isEqual statt ==, z.B. Dies wird Ihren Test bestanden:

class TestObject: NSObject { 

    // ... 

    override func isEqual(object: AnyObject?) -> Bool { 
     guard let other = object as? TestObject else { return false } 
     return self == other 
    } 

}