Ошибка компоновщика OCMock 3.0.2 с тестовым файлом .mm

Я использую OCMock 3.0.2, который я установил через cocoapods для моей цели тестирования:

platform :ios, '7.0'
xcodeproj 'myProject.xcodeproj'

target :myTestTarget do
pod 'OCMock', '~> 3.0.2'
end

link_with "myTestTarget"

В моем тестовом файле (myTest.mm) я включил OCMock и хочу опробовать новую стратегию проверки на месте, например:

- (void) test_myTest
{
MyObject *obj = [MyObject new];
id robotMock = OCMPartialMock(obj);

[obj testMethod];

// some asserts
OCMVerify([obj _internalMethodToBeCalled]);
}

Пока кажется нормальным. Однако, когда я пытался запустить этот конкретный тестовый пример, я получаю ошибку компоновщика:

Undefined symbols for architecture i386:
"OCMMakeLocation(objc_object*, char const*, int)", referenced from:
-[MyTests test_myTest] in MyTests.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Я проверил, что OCMock был загружен правильно и ссылки на файлы OCMLocation.h / m тоже есть. Я вижу, что OCMMakeLocation, кажется, является внешней функцией, но файл .m находится в качестве зависимого проекта в моей цели сборки pods, но каким-то образом он не связан. Я должен сделать свой тест для .mm, так как я включаю некоторые файлы C ++. Почему это будет проблемой для OCMock?

4

Решение

OCMMakeLocation объявлен так

OCMLocation.h:

extern OCMLocation *OCMMakeLocation(id testCase, const char *file, int line);

OCMLocation.m:

OCMLocation *OCMMakeLocation(id testCase, const char *fileCString, int line)
{
return [OCMLocation locationWithTestCase:testCase file:[NSString stringWithUTF8String:fileCString] line:line];
}

Это прямая функция C, определенная вне интерфейса Objective-C. Я недостаточно осведомлен о том, что на самом деле делает компилятор (возможно, кто-то другой может объяснить это лучше), но, насколько я понимаю, это происходит: ваш тестовый файл представляет собой файл Objective-C ++, поэтому он получает соблюдается связь C ++, которая делает искажение имени (увидеть это о названии искажения). Тем не менее, OCMLocation скомпилирован как файл Objective-C, поэтому он получает связь C, а не связь C ++, поэтому нет искажения имени. Поскольку ваш тест соответствует связыванию C ++, он извлекает OCMock.h и предполагает, что это также заголовок C ++, поэтому предполагается, что результат компиляции его исходного кода будет таким же, каким он не будет.

Короче говоря, чтобы это исправить, все, что вам нужно сделать, это сообщить компилятору, что OCMock.h является заголовком C в вашем тестовом файле:

#ifdef __cplusplus
extern "C" {
#endif
#import <OCMock/OCMock.h>
#ifdef __cplusplus
}
#endif
7

Другие решения

Похоже, что вы создаете OCMock из исходного кода, вы создаете его только для x86_64 (64-разрядная версия), а затем пытаетесь использовать двоичный файл в проекте i386 (32-разрядная версия). Использование готовых двоичных файлов, доступных на странице загрузок, должно решить вашу проблему, поскольку эти двоичные файлы жир, они содержат i386 и x86_64.

Это может быть тот случай, когда Cocoapods пытается выполнить сборку Debug, для которой «только активные аргументы» установлены в true. Я не знаю достаточно о Cocoapods, чтобы сказать, как заставить его делать сборку Release, которая должна создавать толстые двоичные файлы.

0

По вопросам рекламы [email protected]