XCTest 输出显示错误但没有抛出错误

XCTest output shows error but no error thrown

我在使用 XCTest 检查是否抛出错误时遇到了一个奇怪的行为。我有一个名为 dispose() 的方法可以抛出如下所示:

func dispose() throws

我在 XCTest 中写了一个单元测试,看起来像这样:

func testDispose() {

    do {
        // sound is properly initialized during setUp()
        try sound.dispose()
    } catch {
        XCTFail("Error thrown.")
    }
}

测试的唯一目的是测试在处置已知处于有效状态的正确初始化对象时是否抛出错误。

测试通过,但在控制台中我得到以下输出:

Test Case '-[LVGSwiftSystemSoundServices_Tests.SystemSoundTypeTests testDispose]' started.
System Sound Services Error: Unspecified error.
    Message: An error occurred while disposing of the SystemSoundID.
    Code: -1500
Test Case '-[LVGSwiftSystemSoundServices_Tests.SystemSoundTypeTests testDispose]' passed (0.015 seconds).

SystemSoundServices Error:...开头的行是错误的description将被抛出如果实际抛出错误。换句话说,即使实际上没有抛出错误,也会创建一个错误并将其描述打印到控制台!

我想不通。测试通过,没有抛出任何错误,但是我的自定义错误信息被打印到控制台。

[编辑 1]:

这是 dispose() 方法的完整代码:

public func dispose() throws {
    try SystemSoundError.check(
        AudioServicesDisposeSystemSoundID(self.soundID),
        message: "An error occurred while disposing of the SystemSoundID." )
}

如果有帮助,SystemSoundError.check(_:message:) 方法是 ErrorType 上的静态方法,如下所示:

enum SystemSoundError: ErrorType, CustomStringConvertible {

    // ...

    public static func check(status: OSStatus, message: String) throws {

        guard status == noErr
            else { throw self.init(status: status, message: message) }
    }
}

[编辑 2]:根据@Lou Franco 的建议,我尝试从单元测试中删除 do-catch 块,如下所示:

func testDispose() {
    try! sound.dispose()
}

我得到相同的结果 - 测试通过(当然 - 其中没有断言)并且没有抛出错误,但我仍然将错误消息打印到控制台。

[编辑 3]:我还在常规应用程序中调用了 try dispose(),没有抛出错误,也没有错误消息打印到控制台。错误消息仅打印到 XCTest 内的控制台。很奇怪。

我想通了,虽然还是很奇怪。如果我在 testDispose() 单元测试中初始化 sound,则不会打印错误消息。

之前,我的测试 class 看起来像这样:

class SystemSoundTypeTests: XCTestCase {

    struct MySystemSound: SystemSoundType {
        var soundID: UInt32
    }

    var sound: MySystemSound!
    let frog = NSURL(fileURLWithPath: "/System/Library/Sounds/Frog.aiff")

    override func setUp() {
        super.setUp()
        do {
            sound = MySystemSound(soundID: try MySystemSound.open(frog))
        } catch {
            print("\(error)")
        }
    }
}

基本上,我不再使用 setup() 来初始化 sound 变量,而是在单元测试中创建它:

func testDispose() {

    do {
        let sound = MySystemSound(soundID: try MySystemSound.open(frog))
        try sound.dispose()
    } catch {
        XCTFail("Error thrown.")
    }
}

当我在单元测试中初始化它时,没有消息打印到控制台。

这是某种奇怪的错误,因为我在同一个 class 中还有大约十几个其他测试,其中一些测试抛出函数,并且 none 表现得像这个。