OCMock 3.0.2链接器错误,带.mm测试文件 [英] OCMock 3.0.2 linker error with .mm test file
问题描述
我使用OCMock 3.0.2,我通过cocoapods为我的测试目标安装:
I am using OCMock 3.0.2, which I've installed through cocoapods for my test target:
platform :ios, '7.0'
xcodeproj 'myProject.xcodeproj'
target :myTestTarget do
pod 'OCMock', '~> 3.0.2'
end
link_with "myTestTarget"
在我的测试文件(myTest.mm)中,我已经包括OCMock,并想要尝试新的验证就地策略,如下:
In my test file (myTest.mm), I've included OCMock and want to try out the new verify-in-place strategy, like so:
- (void) test_myTest
{
MyObject *obj = [MyObject new];
id robotMock = OCMPartialMock(obj);
[obj testMethod];
// some asserts
OCMVerify([obj _internalMethodToBeCalled]);
}
到目前为止似乎正常。但是,当我试图运行这个特定的测试用例,我得到链接器错误:
So far seems normal. However, when I tried to run this specific test case, I am getting linker error:
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)
I验证OCMock被正确拉入,OCMLocation.h / m文件也被引用。我看到OCMMakeLocation似乎是一个extern函数,但是.m文件作为一个依赖项目在我的pods构建目标,但不知何故,它没有被链接。我必须让我的测试是.mm,因为我包括一些c ++文件。为什么会是OCMock的问题?
I verified that OCMock was pulled in correctly and OCMLocation.h/m files are referenced too. I see that OCMMakeLocation seems to be an extern function but the .m file is there as a dependent project in my pods build target, but somehow it is not being linked. I have to make my test to be .mm since I am including some c++ files. Why would this be the problem for OCMock?
推荐答案
OCMMakeLocation声明如下
OCMMakeLocation is declared like this
OCMLocation.h:
OCMLocation.h:
extern OCMLocation *OCMMakeLocation(id testCase, const char *file, int line);
OCMLocation.m:
OCMLocation.m:
OCMLocation *OCMMakeLocation(id testCase, const char *fileCString, int line)
{
return [OCMLocation locationWithTestCase:testCase file:[NSString stringWithUTF8String:fileCString] line:line];
}
这是一个在Objective-C接口之外定义的直接C函数。我不知道编译器实际上在做什么(也许别人可以解释它更好),但为了我的理解,这是发生了什么:你的测试文件是一个Objective-C ++文件,所以它得到遵循C ++链接,这是名称调整(请参阅名称调整)。但是,OCMLocation被编译为一个Objective-C文件,所以它获得C链接,而不是C ++链接,所以没有名称调整。因为你的测试符合C ++链接,它拉入OCMock.h并假定它也是一个C ++头文件,所以它假设编译它的源的结果将是相同的,这不会是。
It's a straight C function defined outside of the Objective-C interface. I'm not knowledgeable enough about what the complier is actually doing (maybe someone else can explain it better), but to the best of my understanding, this is what's going on: Your test file is an Objective-C++ file, so it's getting complied with C++ linkage, which does name mangling (see this about name mangling). However, OCMLocation is compiled as a Objective-C file, so it gets C linkage, not C++ linkage, so no name mangling. Because your test is complied with C++ linkage, it pulls in OCMock.h and assumes it's also a C++ header, so it assumes the result of compiling it's source will be the same, which it's not going to be.
为了解决这个问题,所有你需要做的是告诉编译器OCMock.h是一个C头在你的测试文件:
Long story short, to fix this, all you need to do is tell the compiler that OCMock.h is a C header in your test file:
#ifdef __cplusplus
extern "C" {
#endif
#import <OCMock/OCMock.h>
#ifdef __cplusplus
}
#endif
这篇关于OCMock 3.0.2链接器错误,带.mm测试文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!