如何将XCTAssertNil与可选结构一起使用?

时间:2014-10-31 22:14:20

标签: swift xctest

2016年3月23日更新我刚刚测试了下面的原始示例代码,它在XCode 7.3中编译得很好。看起来像XCTAssertNil一直在更新以采用类型() throws -> Any?的表达式。因此可能不再需要这个问题和答案(旧版本的编译器除外)。

我正在使用XCTest在XCode中编写我的第一个单元测试。我不确定如何利用XCTAssertNil,因为它似乎只在使用某些类型时编译。它似乎可以使用由类和内置基元构成的选项,但不适用于结构。如何使用这种方法?

对于结构体,编译器会给出以下错误(假设'SimpleStruct'是您的类型的名称):

'SimpleStruct' is not identical to 'AnyObject'

这是一个简单的测试类,用于说明一些编译好的类型和其他没有编译的类型。

import Cocoa
import XCTest

struct SimpleStruct {
}

class SimpleClass {
}

class Tests: XCTestCase {

    func testl() {
        var simpleStruct:SimpleStruct? = nil;
        var simpleClass:SimpleClass? = nil;
        var i:Int? = nil;
        var s:String? = nil;
        var tuple:(Int,String)? = nil;

        XCTAssertNil(simpleStruct); // compile error
        XCTAssertNil(simpleClass); // OK
        XCTAssertNil(i); // OK
        XCTAssertNil(s); // OK
        XCTAssertNil(tuple); // compile error
    }

}

1 个答案:

答案 0 :(得分:11)

2016年3月23日更新针对XCode 7.3进行了更新(但如果您看到我对问题的修改,则会显示不再需要此解决方法)

这是一种解决方法。我创建了自己的通用函数:

func AssertNil<T>(@autoclosure expression: () -> T?, message: String = "",
               file: StaticString = #file, line: UInt = #line) {

    if (expression() != nil) {
        XCTFail(message, file:file, line:line)
    }
}

看起来这不应该是必要的。这只是XCTest最初针对Objective-C而没有为Swift更新/桥接的结果吗?

编辑:我已经做了足够多的研究,看到AnyObject可以用来表示任何类而不是结构。但是,这并没有解释为什么我的原始帖子中的代码为Int类型和String类型编译。 (我在其他地方读到Xcode可能会自动将这些转换为NSNumber和NSString,这可能解释了原因。请参阅http://www.scottlogic.com/blog/2014/09/24/swift-anyobject.htmlhttp://www.drewag.me/posts/swift-s-weird-handling-of-basic-value-types-and-anyobject。我将尝试删除导入Foundation的Cocoa导入看看会发生什么)

Edit2:XCTest还导入了Foundation,因此我无法测试我想要的内容。我可以创建自己的方法并测试它。现在,我假设自动转换是允许int和string选项编译的。看起来像XCTest还没有为Swift做好黄金时间。

2015年8月13日更新:编辑该功能以与XCode 7 beta兼容