调用[NSBundle mainBundle]时XCTest失败

时间:2015-03-11 17:36:56

标签: ios unit-testing nsbundle xctest ocmock

我有一些代码在某些时候调用[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警告你:

  

类别正在实施一种方法,该方法也将由其主要类

实施

那么,解决这个问题的正确方法是什么?

1 个答案:

答案 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]