XCTestAssertNil crash due to "nil" parameter

7.8k views Asked by At

I'm using XCTest to write unit tests in my project, and when using the XCAssertNil() or XCAssertNotNil() methods, XCTest framework crashes.

Here's my test:

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

Here's the stack trace:

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.'

It seems that XCTest has a parameter named test which cannot be nil, strange for a method expected to check for nil (or non-nil) values... Does anyone else got this problem and solved it?

6

There are 6 answers

3
Jon Reid On

Since your "test" is nil, I'm guessing you're trying to call XCAssertNil from a standalone function you wrote as a helper. The XCTest assertions take self as "test", so they can't be in standalone functions. They must be in methods. Try changing your helper function to a method.

1
basvk On

Same error occured in a similar situation like this:

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)

So calling XCTAssert after the expectation was fulfilled.
Which ofcourse is wrong.

0
byedissident On

If you are doing an Asynch you need to use a expectation:

//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 }
0
pierre23 On

You can also get this error when the test function finished to execute but than if you have anything async that call any XCTAssert. It will crash your test. I had the same issue...

2
florieger On

According to this rdar http://www.openradar.me/22409527, this seems to be a bug in XCTest, leading to a crash when you check an optional that is nil.

You can fix your test with:

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

As I see in 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);

It's first argument - test - refers to the instance of XCTestCase. So the message might be: "Hey man, your XCTestCase object doesn't exist any more, so I cannot invoke any method on it".

It might be a case for example when you call some XCTAssert... in asynchronous block, that might be invoked long after your enclosing XCTestCase object has gone.

If that might be a case adding [unowned self] to your async block wont solve the issue here, you need to go for Expectations or synchronise your code.