XCTestAssertNil 由于“nil”参数而崩溃

Posted

技术标签:

【中文标题】XCTestAssertNil 由于“nil”参数而崩溃【英文标题】:XCTestAssertNil crash due to "nil" parameter 【发布时间】:2015-09-08 03:31:59 【问题描述】:

我正在使用 XCTest 在我的项目中编写单元测试,当使用 XCAssertNil()XCAssertNotNil() 方法时,XCTest 框架崩溃。

这是我的测试:

XCTAssertNotNil(messageCollection.fieldName, "field_name must be not-nil")

这是堆栈跟踪:

2015-06-22 17:05:17.629 xctest[745:8747] *** Assertion failure in void _XCTFailureHandler(XCTestCase *, BOOL, const char *, NSUInteger, NSString *, NSString *, ...)(), /SourceCache/XCTest_Sim/XCTest-7701/XCTestFramework/OtherSources/XCTestAssertionsImpl.m:41
Test Case '-[Wakanda_ios_Framework_Tests.WAKAdapterTest testEntityCollectionParsing]' started.
2015-06-22 17:05:17.631 xctest[745:8747] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Parameter "test" must not be nil.'

似乎 XCTest 有一个名为 test 的参数,它不能为 nil,这对于预期检查 nil(或非 nil)值的方法来说很奇怪......有其他人遇到这个问题并解决了吗?

【问题讨论】:

我遇到了同样的错误,但情况不同。我认为问题在于我巧妙地滥用了测试 API —— 进行异步测试,并尝试在调用expectation.fulfill() 之后使用XCTAssertEqual 。我的猜测是测试框架没有注意到真正的问题,然后由于看似无关的原因而崩溃。 是的 - 当您调用 expectation.fulfill() 然后订购一些异步代码时,XCTestCase 可能会被卸载。在@MattFenwick 下方查看我的答案 昨天,我在使用 XCAssertNotNil() 和 XCAssertTrue() 函数时遇到了相同的“异常 'NSInternalInconsistencyException',原因:'参数“test”不能为 nil。'”错误。奇怪的是,这些测试已经使用了几个星期,但是当我更改了我一直在测试的函数中的一个参数时,它就开始了。而且这也是一个亮点:异常之后的任何测试都不会运行。我终于解决了这个问题,对项目进行了清理,丢弃了 DerivedData 中的文件夹并重新启动计算机。 Xcode 9.2,顺便说一句。 【参考方案1】:

根据这个 rdar http://www.openradar.me/22409527,这似乎是 XCTest 中的一个错误,当您检查一个为 nil 的可选项时会导致崩溃。

您可以使用以下方法修复您的测试:

XCTAssert(messageCollection.fieldName != nil, "field_name must be not-nil")

【讨论】:

这似乎也不起作用,我仍然得到同样的错误。不过我使用的是 Xcode 8。 @MatthewDrill 您使用的是哪个版本的 Xcode?刚刚在 Xcode 8.2.1 中进行了测试,现在 XCTAssertNotNil() 可以按预期工作,至少对我来说是这样。 var optional: String?XCTAssertNotNil(optional, "field_name must be not-nil")【参考方案2】:

正如我在 XCTestAssertionsImpl.h 中看到的:

XCT_EXPORT void _XCTFailureHandler(XCTestCase *test, BOOL expected, const char *filePath, NSUInteger lineNumber, NSString *condition, NSString * __nullable format, ...) NS_FORMAT_FUNCTION(6,7);

它的第一个参数 - test - 指的是 XCTestCase 的实例。所以消息可能是:“嘿,你的 XCTestCase 对象不存在了,所以我不能调用它上面的任何方法”。

例如,当您在异步块中调用一些 XCTAssert... 时,可能会在您的封闭 XCTestCase 对象消失后很久才调用它。

如果可能是这种情况,将 [unowned self] 添加到您的 async 块并不能解决这里的问题,您需要使用 Expectations 或同步您的代码。

【讨论】:

【参考方案3】:

由于您的“测试”为零,我猜您正试图从您作为助手编写的独立函数中调用XCAssertNil。 XCTest 断言将self 作为“测试”,因此它们不能在独立函数中。它们必须在方法中。尝试将您的辅助函数更改为方法。

【讨论】:

其实我已经在一个测试方法中了,我的其他测试功能如XCTAssertEqual都在正常工作... 很奇怪。尝试在您的测试方法中移动 XCTAssertEqual。它在 XCTAssertNil 旁边有效吗? 我什至没有注意到我是如何使用 XCTAsserts 将代码剪切成辅助函数的,这就是我迷恋的原因!谢谢@JonReid【参考方案4】:

在类似的情况下发生了同样的错误:

let expectation = self.expectation(description: "exp")

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) 
    expectation.fulfill()


DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) 
    XCTAssert(false)


waitForExpectations(timeout: 2, handler: nil)

所以在实现期望后调用XCTAssert。 这当然是错的。

【讨论】:

对我来说同样的问题!【参考方案5】:

您也可以在测试函数完成执行时收到此错误,但如果您有任何异步调用任何 XCTAssert。它会使你的测试崩溃。我有同样的问题...

【讨论】:

【参考方案6】:

如果你在做一个异步,你需要使用一个期望:

//PRIOR TO TEST<br>
let validation = expectation(description: "FullFill")
<br><br>
//AFTER ASYNCH IS COMPLETED<br>
validation.fulfill()

//BOTTOM OF YOUR TEST<br>
self.waitForExpectations(timeout: 10) error in 

【讨论】:

以上是关于XCTestAssertNil 由于“nil”参数而崩溃的主要内容,如果未能解决你的问题,请参考以下文章

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效参数不满足:self.senderId!= nil”

Rails 4 表单数据保存为 Nil

由于该应用程序崩溃,字典得到 nil 值。在展开可选值时意外发现 nil

HTTP POST 请求返回尝试从 objects[0] 插入 nil 对象?

给定 nil 参数时要做啥的 Objective-c 约定?

由于 nil 子视图,无法使用 Xib 文件创建自定义视图