OCMock 3.0.2链接器错误,带.mm测试文件 [英] OCMock 3.0.2 linker error with .mm test file

查看:243
本文介绍了OCMock 3.0.2链接器错误,带.mm测试文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆