简体   繁体   中英

XCTAssertEqual for custom objects in Swift

XCode 6, Beta 5

I have a unit test like this:


    func testMyObjectsEqual()
    {
        //....

        XCTAssertEqual(myObject, myOtherObject, "\(myObject) and \(myOtherObject) should be equal")
    }

XCTAssertEqualObjects is no longer available in Swift since the language makes no distinction between scalars and objects.

So we have to use XCTAssertEqual which leads to the following error:

 "Type MyObject does not conform to protocol Equatable"

The only workaround I have found is to inherit (MyObject) from NSObject so that I can do the following:

 XCTAssert(myObject == myOtherObject, "\(myObject) and \(myOtherObject) should be equal")

So my question is: Is there a way (as of beta 5) to use XCTAssertEqual for custom types without having to rely on NSObject or littering all custom types with "==" overloads?

If you want to compare references in Swift, you can use === operator. This is what happens when you subclass from NSObject (when you are comparing objects in Objective-C using XCTAssertEqual , you are comparing references).

But is this really what you want?

class MyObject {
    var name: String

    init(name: String) {
        self.name = name
    }
}

func testMyObjectsEqual() {
    let myObject = MyObject(name: "obj1")
    let myOtherObject = MyObject(name: "obj1")
    let otherReferenceToMyFirstObject = myObject

    XCTAssert(myObject === myOtherObject) // fails
    XCTAssert(myObject === otherReferenceToMyFirstObject) // passes
}

I guess that when you are comparing custom objects, you probably should make them conform to the Equatable protocol and specify, when your custom objects are equal (in the following case the objects are equal when they have the same name):

class MyObject: Equatable {
    var name: String

    init(name: String) {
        self.name = name
    }
}

func ==(lhs: MyObject, rhs: MyObject) -> Bool {
    return lhs.name == rhs.name
}

func testMyObjectsEqual()
{
    let myObject = MyObject(name: "obj1")
    let myOtherObject = MyObject(name: "obj1")

    XCTAssertEqual(myObject, myOtherObject) // passes
}

Since Xcode 12.5 there is XCTAssertIdentical

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM