XCTAssertEqual用于Swift中的自定义对象

joa*_*kim 17 unit-testing ios swift

XCode 6,Beta 5

我有这样的单元测试:


    func testMyObjectsEqual()
    {
        //....

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

XCTAssertEqualObjects在Swift中不再可用,因为该语言不区分标量和对象.

所以我们必须使用XCTAssertEqual,这会导致以下错误:

 "Type MyObject does not conform to protocol Equatable"

我发现的唯一解决方法是从NSObject继承(MyObject),以便我可以执行以下操作:

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

所以我的问题是:有没有办法(从beta 5开始)将XCTAssertEqual用于自定义类型而不必依赖NSObject或乱丢所有带有"=="重载的自定义类型?

Mar*_*rný 17

如果要比较Swift中的引用,可以使用===运算符.这是从NSObject继承的时候发生的事情(当你在Objective-C中比较对象时XCTAssertEqual,你正在比较引用).

但这真的是你想要的吗?

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

我想当你比较自定义对象时,你可能应该使它们符合Equatable协议,并在你的自定义对象相等时指定(在下面的例子中,当它们具有相同名称时对象是相同的):

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

  • 在我看来,有一个缺少"XCTAssertSame"函数,它将比较对象相等性.虽然写起来很容易. (5认同)