【问题标题】:XCTAssertEqual not working for Equatable types in SwiftXCTAssertEqual 不适用于 Swift 中的 Equatable 类型
【发布时间】:2015-12-06 16:16:35
【问题描述】:

给定以下 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
}

还有一个测试用例:

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

    XCTAssertEqual(a, b) // fails

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

两个断言返回不同的值,但它们都应该通过。

我尝试编写自定义断言函数:

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)
}

但这也失败了:

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

这是怎么回事?

【问题讨论】:

  • +1 用于非常好的分析。不幸的是,我只能猜测问题并建议进一步分析。对我来说,看起来 swift 在某处丢失了您的“TestObject”实现 Equatable 协议的信息。您可以在 Operator 函数中添加“打印”吗?我希望在有问题的情况下不会调用它。此外,我希望以某种方式在“func ==”前面有一个“覆盖”。抱歉,我目前无法提供更好的帮助。
  • @jboi 你是对的 - == 运算符只被调用一次(在 testExample 中的直接调用中),但它应该被调用三次。我不能在顶层使用 override 关键字(这是一个语法错误)。
  • 我认为这与这里的错误/问题有关:stackoverflow.com/questions/31099379/…
  • 仅仅因为你有一个== 函数并不意味着TestObject 符合Equatable 协议。您必须像使用任何其他协议一样显式声明一致性。
  • @PeterSchorn 当然可以,但是在示例中,我的类继承自NSObject,符合Equatable

标签: swift xctest


【解决方案1】:

XCTAssertEqual 调用 isEqual 而不是 ==,例如这将使您的测试通过:

class TestObject: NSObject {

    // ...

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

}

【讨论】:

    【解决方案2】:

    使用 Swift 5?将Equatable 协议添加到您的班级。例如。

    class FooBar : Equatable {
      var foo: Int
      var bar: String
    }
    

    Further discussion on "Hacking With Swift"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-20
      • 2018-10-23
      • 2020-12-04
      • 1970-01-01
      • 2022-08-02
      相关资源
      最近更新 更多