.mm 测试文件的 OCMock 3.0.2 链接器错误

2024-02-02

我正在使用 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 的问题?


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];
}

它是在 Objective-C 接口之外定义的直接 C 函数。我对编译器实际在做什么的了解不够(也许其他人可以更好地解释它),但据我所知,这就是发生的事情:你的测试文件是一个 Objective-C++ 文件,所以它正在符合 C++ 链接,它确实名称修改 (请参阅有关名称修改的内容 http://en.wikipedia.org/wiki/Name_mangling)。然而,OCMLocation 被编译为 Objective-C 文件,因此它获得 C 链接,而不是 C++ 链接,因此没有名称修改。因为您的测试符合 C++ 链接,所以它会引入 OCMock.h 并假设它也是 C++ 标头,因此它假设编译其源代码的结果将是相同的,但事实并非如此。

长话短说,要解决这个问题,您所需要做的就是告诉编译器 OCMock.h 是测试文件中的 C 标头:

#ifdef __cplusplus
extern "C" {
#endif
#import <OCMock/OCMock.h>
#ifdef __cplusplus
}
#endif
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.mm 测试文件的 OCMock 3.0.2 链接器错误 的相关文章

随机推荐