调用 [NSBundle mainBundle] 时 XCTest 失败
XCTest fails when calling [NSBundle mainBundle]
我有一些代码会在某些时候调用 [NSBundle mainBundle]
,主要是 read/set 偏好设置。当我对该方法进行单元测试时,测试失败,因为测试的 mainBundle 不包含该文件。
这是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.
以前,我们的代码库在 NSBundle
的 +mainBundle
class 方法上使用类别覆盖来解决此问题。但是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.
实际上 Xcode 警告你:
Category is implementing a method which will also be implemented by its primary class
那么,解决这个问题的正确方法是什么?
解决此问题的最简单和最干净的方法是在调用 [NSBundle mainBundle]
时将单元测试中的 NSBundle class 部分模拟为 return [NSBundle bundleForClass:[self class]]
。 =15=]
您可以将它放在您的 -setup
方法中,以便在您的整个测试中模拟它 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
干净整洁。
[Source]
我有一些代码会在某些时候调用 [NSBundle mainBundle]
,主要是 read/set 偏好设置。当我对该方法进行单元测试时,测试失败,因为测试的 mainBundle 不包含该文件。
这是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.
以前,我们的代码库在 NSBundle
的 +mainBundle
class 方法上使用类别覆盖来解决此问题。但是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.
实际上 Xcode 警告你:
Category is implementing a method which will also be implemented by its primary class
那么,解决这个问题的正确方法是什么?
解决此问题的最简单和最干净的方法是在调用 [NSBundle mainBundle]
时将单元测试中的 NSBundle class 部分模拟为 return [NSBundle bundleForClass:[self class]]
。 =15=]
您可以将它放在您的 -setup
方法中,以便在您的整个测试中模拟它 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
干净整洁。
[Source]