h.and.h
h.and.h

Reputation: 776

How to use the 'is' operator to unit test conformance to Equatable in Swift

Since we can use 'is' to check for protocol conformance, is there a way to unit test conformance to Equatable using the 'is' operator? Something like:

struct Thing {
    var id: UUID
}

extension Thing: Equatable {
    static func ==(lhs: Thing, rhs: Thing) -> Bool {
        return lhs.id == rhs.id
    }
}



func test_ThingConformsToEquatable() {
    let thing1 = Thing(id: UUID())
    XCTAssert(thing1 is Equatable)
}

This produces "Protocol 'Equatable' can only be used as a generic constraint because it has Self or associated type requirements," and I've read the workarounds to this error on SO, but the 'is' operator is very clean, and I'd like to find a way to unit test for conformance using it. Thanks!

Upvotes: 1

Views: 233

Answers (1)

Rob Napier
Rob Napier

Reputation: 299355

As a rule, this doesn't make a lot of sense as a unit test. If you're relying on Equatable in your code, then if the type isn't Equatable then the code won't compile. If you're not relying on Equatable in your code, it doesn't really matter if the type is Equatable.

That said, it's fine to test this if you like, and maybe you're trying to protect a public interface that you're not using directly. You can test it by relying on the Equatable conformance, forcing the compilation to fail exactly how it will in your code if it relies on the Equatable conformance.

func isEquatable<T: Equatable>(_: T) -> Bool {
    return true
}

func test_ThingConformsToEquatable() {
    let thing1 = Thing(id: UUID())
    XCTAssert(isEquatable(thing1))
}

The beauty of this test case is that if it fails, the test suite will not even compile, so you will discover the error immediately.

You can also skip creating an instance and just test the type directly:

func isEquatable<T: Equatable>(_: T.Type) -> Bool {
    return true
}

func test_ThingConformsToEquatable() {
    XCTAssert(isEquatable(Thing.self))
}

Upvotes: 4

Related Questions