OCUnit 测试在未测试的类中给出错误
我编写了一个 OCUnit 测试,在 Xcode 3.2 中运行良好,现在在 Xcode 4 中遇到问题。它测试类 A
中的单个静态函数 X
>,它不调用任何类或函数(库函数之外)。唯一需要调用的其他代码是静态构造函数,它初始化两个静态变量,但同样,这些是不调用任何其他类或类 A.
然而,我必须包含它导入的所有类以及它们导入的所有类的 .m、.mm 和 .c 文件,等等,以解决_OBJC_CLASS_$_ClassB”问题,引用自:B' 的错误。 为什么在
类上调用静态构造函数?最好不要更改我的类来适应测试?
没有以任何方式引用的 >更新
为了进一步弄清楚发生了什么,我注释掉了所有测试用例和#import "Ah"
以查看会发生什么:
- (void) testSomething {
STAssertTrue(NO, @"did it work?");
}
< em>仍然,我的 +[Binitialize]
被调用并失败了,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 <????> ()
I have written an OCUnit test, which ran fine in Xcode 3.2, and now I'm having problems with it in Xcode 4. It tests a single static function X
in class A
, which doesn't call any classes or functions (outside of library functions). The only other code that should need to be called is the static constructor, which initializes two static variables, but again, those are hardcode values (arrays) that don't call any other classes, or functions of class A
.
And yet, I had to include the .m, .mm, and .c files for all classes that it imports, and that they import, and so on, to solve the _OBJC_CLASS_$_ClassB", referenced from: errors. I don't recall having to do any of that in Xcode 3, but fine, no problem, I got it to compile. Now, I'm getting errors originating from class B
's +[B initialize]
.
Why is the static constructor getting called on a class that is not referenced in any way? How can I fix this, ideally without changing my classes to acommodate the testing?
Update
To further figure out what's going on, I commented out all my test cases and the #import "A.h"
to see what would happen. I added a single simple unit test:
- (void) testSomething {
STAssertTrue(NO, @"did it work?");
}
Still, my +[B initialize]
gets called and fails. It seems that OCUnit is crawling through all of my classes, and their +initialize
methods are getting called in the process. This makes no sense to me - how can I disable this behavior?
Here is the stack trace before my own code gets called, in case it helps:
#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 <????> ()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在使用 xcode 4 和我的单元测试套件时也遇到了很多问题。
我必须查看您的源代码才能了解您的情况,但 OCUnit 确实通过类反射做了很多事情。这就是它运行以“test”开头的方法的方式。因此,它检查您的类,导致其类初始值设定项触发,这是有道理的。
我知道这可能不是您正在寻找的答案,但是如果 B 的 +initialize 中的错误是因为它依赖于某种预期的应用程序状态,那么您可能真的需要考虑重构 +initialize。由于这个确切的原因,它不应该依赖于类本身之外的任何东西......你无法保证它何时会触发或事物将处于什么状态。
I had a number of problems with xcode 4 and my unit test suites as well.
I'd have to see your source to know what's going on in your case, but OCUnit does do a lot of stuff through reflection on classes. That's how it figures out to run methods that start with "test". So it makes some sense that it's inspecting your classes, causing their class initializers to fire.
I know this probably isn't the answer you're looking for, but if the errors in B's +initialize are because it's relying on some sort of expected application state, you may really want to consider refactoring +initialize. It shouldn't be dependent on anything outside the class itself for this exact reason... you have no guarantees on when it will fire or what state things will be in.
DougW 是正确的,我在 +initialize 方法中做的事情可能不应该在那里。无论如何,我还没有准备好重构它,以便我的单元测试能够运行。
我使用下面的代码来跳过该代码,这首先是我的单元测试不需要的。我希望这对其他人有帮助,因为它在任何函数中都很有用,而不仅仅是静态初始化程序。
DougW is correct, that I'm doing things in my +initialize method that probably shouldn't be in there. In any case, I wasn't ready to refactor that only so my unit tests would run.
I used the code below to skip that code, which wasn't required by my unit tests in the first place. I hope this helps someone else out there, as it would be useful in any function, not just the static initializer.