Я запускаю модульные тесты своего iOS-приложения на Xcode 9 GM, и некоторые из них не работают со странным NSInternalInconsistencyException, жалуясь на то, что некоторые тестовые утверждения не могут быть представлены, потому что связанные тесты не имеют связанного объекта XCTestRun. Я использую OCMockito + OCHamcrest для имитации и проверки звонка.
В демонстрационных целях предположим, что мое приложение называется MyTestApp, и у меня есть тестовый класс FooTest (который наследуется от XCTestCase). В -setUp я создаю и связываю вместе различные имитационные объекты для тестов, а в -tearDown я на всякий случай устанавливаю их равными нулю.
Вот пример получаемого мной исключения:
2017-09-19 13:23:01.852729-0700 xctest[17006:5392130] *** Assertion failure in -[FooTest recordFailureWithDescription:inFile:atLine:expected:], /Library/Caches/com.apple.xbs/Sources/XCTest_Sim/XCTest-13201/Sources/XCTestFramework/Core/XCTestCase.m:308 /Users/fooUser/Workspaces/MyTestApp/tests/FooTest.mm:46: error: -[FooTest testSomething] : failed: caught "NSInternalInconsistencyException", "Unable to report test assertion failure 'Expected 1 matching invocation, but received 0' from /Users/fooUser/Workspaces/MyTestApp/tests/FooTest.mm:135 because it was raised inside test case -[FooTest testSomethingElse] which has no associated XCTestRun object. This may happen when test cases are constructed and invoked independently of standard XCTest infrastructure." ( 0 CoreFoundation 0x000000010255d1cb __exceptionPreprocess + 171 1 libobjc.A.dylib 0x0000000101ebff41 objc_exception_throw + 48 2 CoreFoundation 0x0000000102562362 +[NSException raise:format:arguments:] + 98 3 Foundation 0x0000000101827089 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193 4 XCTest 0x0000000101d96875 -[XCTestCase recordFailureWithDescription:inFile:atLine:expected:] + 518 5 MyAppUnitTests 0x000000011d7f2f5a -[HCXCTestFailureReporter executeHandlingOfFailure:] + 154 6 MyAppUnitTests 0x000000011d7f2b73 -[HCTestFailureReporter handleFailure:] + 67 7 MyAppUnitTests 0x000000011d64ec9a MKTFailTest + 217 8 MyAppUnitTests 0x000000011d64c3f4 -[MKTExactTimes verifyData:] + 254 9 MyAppUnitTests 0x000000011d64f2ba -[MKTBaseMockObject verifyInvocation:usingVerificationMode:] + 137 10 MyAppUnitTests 0x000000011d64f20b -[MKTBaseMockObject handlingVerifyOfInvocation:] + 115 11 MyAppUnitTests 0x000000011d64f15a -[MKTBaseMockObject forwardInvocation:] + 64 12 CoreFoundation 0x00000001024dfed8 ___forwarding___ + 760 13 CoreFoundation 0x00000001024dfb58 _CF_forwarding_prep_0 + 120 14 MyAppUnitTests 0x000000011c40b486 -[FooTest setUp] + 294 15 XCTest 0x0000000101d97b39 __24-[XCTestCase invokeTest]_block_invoke_3 + 31 16 XCTest 0x0000000101d97809 __24-[XCTestCase invokeTest]_block_invoke + 271 17 XCTest 0x0000000101ddff45 -[XCUITestContext performInScope:] + 183 18 XCTest 0x0000000101d976ef -[XCTestCase invokeTest] + 141
Следует отметить несколько моментов:
- The unit tests are not initializing XCTestCase or any XCTest "infrastructure" classes outside of the XCTest framework.
- The remaining statements of the affected unit tests actually gets executed, up to the point of the exception.
- The implicated line of code looks like:
[verify(_mockTestObject) description];
- The stack trace is lying about where the problem occurs - it says that it's in -setUp, but from what I can tell, OCMockito simply reports expectation failures at the beginning of the next unit test's run. The problem location (FooTest.mm:135) looks like the above verify() call.
Фактически, все модульные тесты, которые терпят неудачу из-за этого исключения, терпят неудачу, потому что мы пытаемся проверить, что -[NSObject description]
был вызван для того или иного фиктивного объекта. При удалении всех экземпляров проверки этого вызова тесты проходят.
Я искал в Google другие экземпляры этого конкретного исключения NSInternalInconsistencyException, и это не дало никаких результатов. Я не уверен, каким образом - [описание NSObject] отличается от любого другого метода, который может быть вызван для фиктивного объекта - возможно, что проблемы на самом деле нет, но она просто проявляется таким образом. Я также пытался найти, есть ли какие-либо параметры отладки / диагностики, которые я могу включить для XCTest, чтобы я мог получить более подробную информацию журнала о выполнении теста, но я тоже не нашел ничего подобного.
Есть идеи, где мне искать дальше? Большое спасибо!