iPhone单元测试:调用自定义代码时未找到符号

时间:2010-01-06 13:17:54

标签: iphone unit-testing symbols

我正在尝试为我的iPhone应用程序设置单元测试。我跟着Apple Unit Testing documentation通过了,并且这很好,但是当我在该测试中添加另一个类时,我收到以下错误:

  "_OBJC_CLASS_$_RootViewController", referenced from:
      __objc_classrefs__DATA@0 in AppDelegateTests.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

应用程序本身是一个基本的导航应用程序,带有用于数据存储的核心数据。

单元测试如下:

#import <SenTestingKit/SenTestingKit.h>
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

#import "HSStabilityAppAppDelegate.h"
#import "RootViewController.h"
@interface AppDelegateTests : SenTestCase {
 HSStabilityAppAppDelegate *appDelegate;
}
@end


@implementation AppDelegateTests
// all code under test must be linked into the Unit Test bundle


#pragma mark -
#pragma mark Set up and tearDown

#if APPLICATION_TESTS
- (void) setUp {
 appDelegate = (HSStabilityAppAppDelegate *)[[UIApplication sharedApplication] delegate];
 STAssertNotNil(appDelegate, @"Cannot find the application delegate.");
}

- (void) tearDown {
 [appDelegate release];
}

#else

#endif


#pragma mark -
#pragma mark Tests

#if APPLICATION_TESTS

- (void) testRootViewIsOnTop {
 id topViewControllerClass = [[appDelegate.navigationController topViewController] class];
 id rootViewControllerClass = [RootViewController class];
 STAssertEquals(topViewControllerClass, rootViewControllerClass, @"Root view controller was not the top class");
}

#endif

@end

如果我注释掉id rootViewControllerClass行,那么程序正确链接。 此外,这仅在构建设备目标时发生,如果构建模拟器,我没有任何问题(可能是因为应用程序测试在模拟器上不起作用)。

任何人都可以帮助解决这个基本且非常令人愤怒的问题吗?

2 个答案:

答案 0 :(得分:4)

我还关注了Apple's iPhone Unit Testing Applications文档,并在尝试对我的某个类进行单元测试时发现了类似于问题中描述的链接错误。

看起来您的单元测试类中引用的任何类都需要添加到该测试目标,因此从测试目标运行。为此,您可以右键单击RootViewController类,然后单击“获取信息”(Cmd-i快捷方式)。在目标窗格中,确保检查单元测试目标(例如,“LogicTests”,如果您已遵循该文档中的命名)。

现在该类将使用您的测试进行编译,并且应该可用于您的单元测试。要仔细检查,请展开“群组和群组”中的“目标/逻辑测试/编译资源”节点。左侧的文件浏览器。这列出了构建目标时可用的所有类文件,现在应该包括您的单元测试类以及您正在测试的类。

(请注意,在创建新应用程序或测试类时,您需要同样选择所有适当的目标 - 在命名文件时,在“新建文件...”窗口的同一页面上)。

(顺便说一句,我正在使用XCode 3.2.3和OS 4.0)。

答案 1 :(得分:1)

我相信我找到了答案。问题是,虽然编译器可以看到定义,但在链接它们时它并没有找到正确的位置,因此抛出这些错误。因此,如果我们将类名解析移动到运行时,我们可以绕过这一切。

而不是:NSManagedObject 使用:NSClassFromString("@NSManagedObject")

这适用于几乎所有定义的类。

如果有人能告诉我如何在编译时使其工作,我仍然非常感激。