我有一些代码在某些时候调用[NSBundle mainBundle]
,主要是读取/设置首选项。当我对方法进行单元测试时,测试失败,因为测试的mainBundle不包含该文件。
这是a known issue,Apple认为它不会被修正not a bug:
他们回复的要点是XCTest通过返回它自己的主包而不是测试目标包来正常工作。
以前我们的代码库在NSBundle
的{{1}}类方法上使用类别覆盖来解决此问题。但是this is dangerous because the behaviour of overriding an existing method in a category is undefined。
如果在类别中声明的方法的名称与原始类中的方法相同,或者在同一个类(或甚至是超类)中的另一个类别中的方法相同,则行为未定义为哪个方法实现在运行时使用。
实际上Xcode警告你:
类别正在实施一种方法,该方法也将由其主要类
实施
那么,解决这个问题的正确方法是什么?
答案 0 :(得分:9)
解决此问题的最简单,最简洁的方法是在您调用[NSBundle bundleForClass:[self class]]
时,在单元测试中部分模拟NSBundle类以返回[NSBundle mainBundle]
。
您可以将它放在-setup
方法中,以便为整个测试类进行模拟:
static id _mockNSBundle;
@implementation MyTests
- (void)setUp
{
[super setUp];
_mockNSBundle = [OCMockObject niceMockForClass:[NSBundle class]];
NSBundle *correctMainBundle = [NSBundle bundleForClass:self.class];
[[[[_mockNSBundle stub] classMethod] andReturn:correctMainBundle] mainBundle];
}
@end
干净整洁。
[Source]