测试对象是否实现协议

use*_*195 4 swift

使用单元测试框架,

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

XCTAssertNotNil(car, "Expecting instance not null")
Run Code Online (Sandbox Code Playgroud)

不起作用,不知道为什么(导致“IVehicle 不符合协议 AnyObject”编译器错误)。

car as Car有效:

XCTAssertNotNil(car as Car, "Expecting instance not null")
Run Code Online (Sandbox Code Playgroud)

这不起作用说测试总是正确的,不确定我们如何测试协议的一致性?

XCTAssertTrue(car is IVehicle, "Expecting instance implements IVehicle")
Run Code Online (Sandbox Code Playgroud)

Air*_*ity 5

首先,

\n\n
XCTAssertNotNil(car, "Expecting instance not null")\n
Run Code Online (Sandbox Code Playgroud)\n\n

假设IVehicle是一个协议,您将得到的错误是因为这意味着它不是第一个参数AnyObject所需要的(只能表示类,不能表示结构或协议)。这可能有点令人沮丧,因为表明它是为了测试选项是否设置为 nil,但你已经有了它。XCTAssertNotNilAnyObjectXCTAssertNotNil

\n\n

下一个:

\n\n
XCTAssertNotNil(car as Car, "Expecting instance not null")\n
Run Code Online (Sandbox Code Playgroud)\n\n

这可以编译,但它可能没有 \xe2\x80\x99t \xe2\x80\x9cworked\xe2\x80\x9d... 如果car不是 a Car,您将得到运行时异常而不是断言失败。这是因为car as Car强制编译器将左侧表达式视为右侧类型,无论它是否是右侧类型(假设至少在某些情况下 \xe2\x80\x93 是有效的转换,如果它不是 \xe2\ x80\x99根本不可能,你\xe2\x80\x99会得到编译器错误)。如果在运行时它不是有效的转换,则您将遇到运行时失败。

\n\n

如果您不确定,安全地转换car为 a 的方法是使用. 所以这应该会给你你想要的结果:Caras?

\n\n
XCTAssertNotNil(car as? Car, "Expecting instance not null")\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将导致Some(car)如果它确实是 a Car,或者nil如果它不是 \xe2\x80\x99t ,则正确触发测试断言。

\n\n

或者你也可以这样写:

\n\n
XCTAssert(car is Car, "Expecting car to be a Car")\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后,

\n\n
car is IVehicle\n
Run Code Online (Sandbox Code Playgroud)\n\n

始终为真,因为编译器在编译时知道 car 变量的类型,并且完全知道 it\xe2\x80\x99sIVehicle是其类型 \xe2\x80\x94 。所以它假设你是偶然写下这个的,因为它不可能是假的,并且它告诉你这一点。

\n