调用[NSBundle mainBundle]时XCTest失败

KPM*_*KPM 3 unit-testing ocmock nsbundle ios xctest

我有一些代码[NSBundle mainBundle]在某些时候调用,主要是读取/设置首选项.当我对方法进行单元测试时,测试失败,因为测试的mainBundle不包含该文件.

这是一个众所周知的问题,Apple不会修复,因为他们认为这不是一个bug:

他们回复的要点是XCTest通过返回它自己的主bundle而不是测试目标的bundle来正常工作.

以前我们的代码库是用一个类别覆盖NSBundle+mainBundle类的方法来解决这个问题.但这很危险,因为覆盖类别中现有方法的行为是未定义的.

如果在类别中声明的方法的名称与原始类中的方法相同,或者在同一个类(或甚至是超类)上的另一个类别中的方法相同,则关于在哪个方法实现中使用哪个方法实现的行为是未定义的.运行.

实际上Xcode警告你:

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

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

KPM*_*KPM 9

解决此问题的最简单,最干净的方法是部分模拟单元测试中的NSBundle类,以便[NSBundle bundleForClass:[self class]]在调用时返回[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
Run Code Online (Sandbox Code Playgroud)

干净整洁.

[ 来源 ]

  • 如何在Swift中做到这一点? (2认同)