XCTest fails when calling [NSBundle mainBundle]

佐手、 提交于 2019-12-01 06:43:29

问题


I have some code that calls [NSBundle mainBundle] at some point, mainly to read/set preferences. When I unit test the method, the test fails because the test's mainBundle does not contain the file.

This is a known issue, that Apple won't fix as they consider it is not a bug:

the gist of their reply is that XCTest is working correctly by returning it’s own main bundle instead of the bundle of the test target.

Previously our codebase was using a category override on NSBundle's +mainBundle class method to work around this. But this is dangerous because the behaviour of overriding an existing method in a category is undefined.

If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime.

Actually Xcode warns you about it:

Category is implementing a method which will also be implemented by its primary class

So, what is the proper method to address the issue?


回答1:


The simplest and cleanest way of fixing this issue is to partially mock the NSBundle class in your unit tests to return [NSBundle bundleForClass:[self class]] when you call [NSBundle mainBundle].

You may put this in your -setup method so that it is mocked for your entire test class:

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

Nice and clean.

[Source]



来源:https://stackoverflow.com/questions/28993551/xctest-fails-when-calling-nsbundle-mainbundle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!