4

Using unit testing framework,

var car: IVehicle = Vehicle.getInstance("mycar") //dictionary

XCTAssertNotNil(car, "Expecting instance not null")

didn't work, not sure why (results in "IVehicle does not conform to protocol AnyObject" compiler error).

But car as Car worked:

XCTAssertNotNil(car as Car, "Expecting instance not null")

This didn't work saying is test is always true, not sure how can we test for conformance of a protocol?

XCTAssertTrue(car is IVehicle, "Expecting instance implements IVehicle")
Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
user2727195
  • 7,122
  • 17
  • 70
  • 118
  • 1
    You should be more descriptive than "didn't work". There isn't only one way things can "not work". – zneak Dec 15 '14 at 17:34
  • For your `car as Car` case, it's because `as` cannot return `nil`. It will crash your program if the cast is invalid. Use `as?` if you want to get nil if the object isn't a Car. – zneak Dec 15 '14 at 17:36
  • If your class is a subclass of NSObject, you could check the conformance using the NSObject method, conformsToProtocol: method. – Sandeep Dec 15 '14 at 17:48

2 Answers2

5

Firstly,

XCTAssertNotNil(car, "Expecting instance not null")

Assuming IVehicle is a protocol, the error you'll get is because that means it is not an AnyObject which is what XCTAssertNotNil requires as a first parameter (AnyObject can only represent classes, not structs or protocols). This is perhaps a bit frustrating because XCTAssertNotNil suggests it is for testing if optionals are set to nil, but there you have it.

Next:

XCTAssertNotNil(car as Car, "Expecting instance not null")

This compiles, but it probably hasn’t “worked”... if car is ever not a Car, you will get a runtime exception and not an assertion failure. This is because car as Car forces the compiler to treat the left-hand expression as the right-hand type no matter whether it is or not (assuming that is a valid cast under at least some circumstances – if it isn’t possible at all, you’ll get a compiler error). If at runtime it isn’t a valid cast, you’ll get a runtime failure.

The way to safely cast car to a Car if you’re not sure, is with as?. So this should give you the results you want:

XCTAssertNotNil(car as? Car, "Expecting instance not null")

This will result in Some(car) if it is indeed a Car, or nil if it isn’t, properly triggering the test assertion.

Alternatively you could just write:

XCTAssert(car is Car, "Expecting car to be a Car")

Finally,

car is IVehicle

is always true because the compiler knows the type of the car variable at compile time, and knows full well that it’s a IVehicle — that is its type. So it assumes you wrote this by accident since it cannot possibly ever be false, and it tells you so.

Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
1

If your class inherits from NSObject you can also use this: -

conforms(to aProtocol: Protocol) -> Bool

It returns a Boolean value that indicates whether the receiver conforms to a given protocol

for example: -

 XCTAssertTrue(sut.conforms(to: CXProviderDelegate.self))
Mussa Charles
  • 4,014
  • 2
  • 29
  • 24