2

我编写了一个 OCUnit 测试,它在 Xcode 3.2 中运行良好,现在我在 Xcode 4 中遇到了问题。它测试了Xclass 中的单个静态函数A,它不调用任何类或函数(在库函数之外)。唯一需要调用的其他代码是静态构造函数,它初始化两个静态变量,但同样,这些是不调用任何其他类或类函数的硬编码值(数组)A

然而,我必须为它导入的所有类以及它们导入的所有类包含 .m、.mm 和 .c 文件等等,以解决_OBJC_CLASS_$_ClassB",引用自:错误。我不不记得必须在 Xcode 3 中执行任何操作,但是很好,没问题,我可以编译它。现在,我收到了源自 classB的错误+[B initialize]

为什么在没有以任何方式引用的类上调用静态构造函数?我该如何解决这个问题,理想情况下不改变我的课程来适应测试?

更新

为了进一步弄清楚发生了什么,我注释掉了我所有的测试用例#import "A.h",看看会发生什么。我添加了一个简单的单元测试:

- (void) testSomething {
    STAssertTrue(NO, @"did it work?");
}

尽管如此,我+[B initialize]的被调用并失败了。似乎 OCUnit 正在遍历我所有的类,并且+initialize在此过程中调用了它们的方法。这对我来说毫无意义 - 我怎样才能禁用这种行为?

这是调用我自己的代码之前的堆栈跟踪,以防万一:

#7  _class_initialize ()
#8  prepareForMethodLookup ()
#9  lookUpMethod ()
#10 objc_msgSend ()
#11 +[NSObject(SenTestRuntimeUtilities) senIsASuperclassOfClass:] ()
#12 +[NSObject(SenTestRuntimeUtilities) senAllSubclasses] ()
#13 +[SenTestSuite updateCache] ()
#14 +[SenTestSuite suiteForBundleCache] ()
#15 +[SenTestSuite testSuiteForBundlePath:] ()
#16 +[SenTestProbe specifiedTestSuite] ()
#17 +[SenTestProbe runTests:] ()
#18 <????> ()
#19 <????> ()
#20 <????> ()
#21 <????> ()
4

2 回答 2

2

我在使用 xcode 4 和我的单元测试套件时也遇到了很多问题。

我必须查看您的消息来源才能了解您的情况,但是 OCUnit 确实通过对类的反射做了很多事情。这就是运行以“test”开头的方法的方式。所以它检查你的类是有道理的,导致它们的类初始化器被触发。

我知道这可能不是您要寻找的答案,但是如果 B 的 +initialize 中的错误是因为它依赖于某种预期的应用程序状态,那么您可能真的需要考虑重构 +initialize。由于这个确切的原因,它不应该依赖于类本身之外的任何东西......你不能保证它什么时候会触发或者事情会处于什么状态。

于 2011-03-16T23:15:06.030 回答
1

DougW 是正确的,我在 +initialize 方法中做的事情可能不应该在那里。无论如何,我还没有准备好重构它,只是为了让我的单元测试能够运行。

我使用下面的代码跳过了我的单元测试首先不需要的代码。我希望这对其他人有所帮助,因为它在任何函数中都很有用,而不仅仅是静态初始化程序。

+ (void)initialize
{
    if (NSClassFromString(@"SenTestSuite")) {
        NSLog(@"Not initializing 'B' class, because unit tests are running");
        return;
    }

    ...
}
于 2011-03-18T18:57:40.433 回答