Использование OCMock 1.77 для модульного и прикладного тестирования с iOS4 и Xcode 4/SDK4.3

Я пытаюсь использовать OCMock 1.77 для тестирования модулей и приложений с iOS4 и Xcode 4/SDK4.3. Я следовал инструкциям по использованию OCMock в качестве статической библиотеки, найденной здесь: http://www.mulle-kybernetik.com/software/OCMock/. Модульные и прикладные тесты работают без OCMock.

Когда я добавляю OCMock и пытаюсь запустить набор тестов OCMock для симулятора (модульные тесты), мой тестовый стенд вылетает с кодом 134. Тестовый стенд работает нормально для устройства (тесты приложений). Если я загляну в консоль, то увижу сообщение ниже - это говорит о том, что я не добавил флаг компоновщика -force_load в соответствии с инструкциями по приведенному выше URL. Но у меня есть... Есть мысли?

Я посмотрел на это: тестовая установка вышла ненормально с кодом 134 с проверкой OCMock на iOS 4, которая предполагает, что это поведение является ошибкой - но я не уверен, что это та же самая ситуация, так как я запускаю тестовый набор OCMock. Если это ошибка, есть ли обходной путь для использования макетов в модульном тестировании?

ТИА.

=====

Консольный вывод:

3/30/11 1:02:32 AM  otest[38552]    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '** Expected method not present; the method getArgumentAtIndexAsObject: is not implemented by NSInvocation. If you see this exception it is likely that you are using the static library version of OCMock and your project is not configured correctly to load categories from static libraries. Did you forget to add the -force_load linker flag?'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x004a05a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x002cf313 objc_exception_throw + 44
    2   CoreFoundation                      0x00458ef8 +[NSException raise:format:arguments:] + 136
    3   CoreFoundation                      0x00458e6a +[NSException raise:format:] + 58
    4   LogicTests                          0x00f89de4 +[OCMockObject initialize] + 115
    5   libobjc.A.dylib                     0x002cfd9b _class_initialize + 380
    6   libobjc.A.dylib                     0x002d773f prepareForMethodLookup + 73
    7   libobjc.A.dylib                     0x002ce069 lookUpMethod + 86
    8   libobjc.A.dylib                     0x002ce1d6 _class_lookupMethodAndLoadCache + 40
    9   libobjc.A.dylib                     0x002e10e3 objc_msgSend + 87
    10  SenTestingKit                       0x20108824 +[NSObject(SenTestRuntimeUtilities) senAllSubclasses] + 107
    11  SenTestingKit                       0x201074a7 +[SenTestSuite updateCache] + 39
    12  SenTestingKit                       0x20107443 +[SenTestSuite suiteForBundleCache] + 92
    13  SenTestingKit                       0x201073a4 +[SenTestSuite testSuiteForBundlePath:] + 108
    14  SenTestingKit                       0x2010606b +[SenTestProbe specifiedTestSuite] + 332
    15  SenTestingKit                       0x20106792 +[SenTestProbe runTests:] + 156
    16  otest                               0x000023c7 0x0 + 9159
    17  otest                               0x000025f2 0x0 + 9714
    18  otest                               0x0000209a 0x0 + 8346
    19  otest                               0x00002049 0x0 + 8265
)

2 ответа

Решение

Я могу воспроизвести это, удалив флаг -force_load. Убедитесь, что он установлен на вашей цели тестирования, а не на основной цели, и что она указывает на правильное расположение статической библиотеки. В моем случае это

-force_load $(PROJECT_DIR)/Libraries/libOCMock.a

Другой ТАК вопрос, который вы связали, просто говорит, что когда verify метод терпит неудачу, он выдает исключение из метода категории в NSInvocation, что приводит к сбою otest. Это все еще работает; сообщение является более загадочным, чем ошибка подтверждения, которую XCode помечает как ошибку в вашем тестовом классе.

  • Загрузите OCMock *.** с http://ocmock.org/ (На момент написания этой статьи 1.77)
  • распаковать в OCMock/ (или другую папку) -> У вас будет две папки "Release" и "Source"
  • Скопируйте папку "Release/Library" в папку вашего проекта xCode
  • Свяжите свой файл с помощью xcode, перетаскивая всю папку "Library" внутри вашего объекта
    • Выберите в качестве цели приложение TEST target!
  • Перейдите в "настройки сборки" вашей тестовой цели
    • В разделе "Пути поиска" добавьте: +"Пути поиска заголовка" -> вставьте путь к заголовкам OCMock (.h) (что-то вроде $(PROJECT_DIR)/Library/Headers) +"Пути поиска библиотеки" -> вставьте путь к вашей библиотеке OCMock (.a) (что-то вроде $(PROJECT_DIR)/Library/) Примечание: в качестве пути вы также можете использовать $ (PROJECT_DIR) или $(SRCROOT)/ и установить рекурсивный флажок, чтобы избежать вставки пути ocmplete
      • Под "Linking" добавьте: +"Другие флаги Link" -> -all_load

Теперь все должно работать правильно. Для проверки:

#import <OCMock/OCMock.h>
// simple test to ensure building, linking, 
// and running test case works in the project
- (void)testOCMockPass {
id mock = [OCMockObject mockForClass:NSString.class];
[[[mock stub] andReturn:@"mocktest"] lowercaseString];
NSString *returnValue = [mock lowercaseString];
STAssertEqualObjects(@"mocktest", returnValue, @"Should have returned the expected string.");
}

- (void)testOCMockFail {
id mock = [OCMockObject mockForClass:NSString.class];
[[[mock stub] andReturn:@"mocktest"] lowercaseString];
NSString *returnValue = [mock lowercaseString];
STAssertEqualObjects(@"thisIsTheWrongValueToCheck", returnValue, @"Should have returned the expected string."); 
}

Большое спасибо:

Энрико Боттани

Другие вопросы по тегам