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”
由于该应用程序崩溃,字典得到 nil 值。在展开可选值时意外发现 nil
HTTP POST 请求返回尝试从 objects[0] 插入 nil 对象?