构建单元测试目标时出现链接错误

51

我有一个带有常规目标和单元测试目标的XCode4 / iOS项目。除了在尝试在我的测试类中#import一个类并尝试使用它时出现问题之外,一切都正常。如果我尝试构建单元测试目标,我会收到以下链接错误:

Undefined symbols for architecture i386:
  "_OBJC_CLASS_$_FRRCategory", referenced from:
      objc-class-ref in CategoryTests.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status

在 CategoryTests.m 中,我是以这种方式导入头文件的:

#import "../todoro/FRRCategory.h"

我哪里做错了?


你的常规目标是应用程序还是静态库? - Jon Reid
5个回答

165

请按照这里的说明操作。无需添加任何文件来编译源代码。

我最初忽略了“默认情况下隐藏符号=否”应该为您的应用程序目标,而不是测试目标。

无论如何(商标),它对我起作用了。


1
这是我认为大多数人想跟随的答案,而不是问问题者选中的答案。这样构建的应用程序产品就像是独立使用的,而测试则链接到它。另一种选择是要复制所有构建设置、链接器设置等,以便单独构建源代码和单元测试。 - febeling
3
笑,即使我读了你的评论,我还是搞错了,需要在我的应用程序目标上使用“默认情况下隐藏符号=否”,而不是测试目标。+1 - ColdLogic
4
这确实是唯一正确的答案。其他的答案将你的源代码复制成两份,组合成测试捆绑包。虽然通常这种做法没问题,但如果构建工具链中存在 bug,你可能会遇到非常奇怪和难以调试的副作用。 - mxcl
1
默认情况下隐藏的符号 = NO 调试模式解决了我的问题,即使是对于我新添加的测试目标,也适用。谢谢。 - xySVerma
1
这个解决方案似乎不适用于扩展单元测试,更多的解决方案在这里:https://dev59.com/BmAf5IYBdhLWcg3wdCh1 - yurgis
显示剩余7条评论

22

请确保已将 FRRCategory 源文件添加到单元测试目标的编译源代码中。

Xcode 4:

项目导航器 -> "[项目名称]" -> 在 Targets 下选择您的单元测试目标 -> Build Phases -> 展开 Compile Sources -> 点击底部的“+”,并添加正确的源文件。


1
将文件添加到编译源中后,错误消失了。那些“编译源”是什么,为什么要强制手动添加来自主目标的文件呢? - cfischer
1
每个目标使用独立的源文件集。要么您没有将测试目标创建为主目标的副本,要么在创建“FRRCategory”时您没有选择两个目标。 - Jano
4
这取决于你使用的单元测试框架。你是使用随 Xcode 4 一起提供的 SenTestingKit 还是其他框架?如果你使用的是 SenTestingKit,那么你不要将被测试的代码添加到测试目标中。 - Jon Reid
27
在我看来,这不是正确的答案。请查看下面的答案。 - carlos
以下答案是迄今为止最好的答案,尤其是如果你有很多资源。 - Hulvej
显示剩余4条评论

7

你可能会遇到的另一个问题是,如果您的单元测试使用了在实际应用程序中未使用的C函数(或类似函数),则会出现问题。

这可能仅限于子项目。就我而言,

  • 应用程式
    • 子项目
      • 嵌入的C库(即直接编译为.c和.h文件)

我的单元测试使用了一些未在其他任何地方使用的C函数,并且这些函数已从应用程序二进制文件中剥离(而不是从子项目的.a文件中剥离)。

解决方法是:

  1. 关闭应用程序的Debug构建中的“死代码剥离”功能*,并且
  2. 确保单元测试使用调试模式而非发布模式,在方案设置中。

(*不要对发布配置执行此操作,因为它会使应用程序膨胀,其中包含从未被调用的代码)。


尝试在设备架构arm64上运行单元测试时出现了这个问题。谢谢。 - amleszk

1

如果你的文件在一个框架内部,那么你只需要引用导入文件夹。否则,一旦将文件添加到项目中,只需执行#import "FRRCategory.h"即可。当然,除非你在头文件搜索路径上做了一些奇怪的事情。


它没有消除错误,但我不知道不需要包含文件夹。谢谢! - cfischer

0
在我的情况下,主机应用程序是“自定义”。我必须将其更改为iOS目标,并设置“允许测试主机应用程序API”。您可以在测试目标的常规选项卡中找到它。

Host Application setting


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接