Сбой XCTest при вызове [NSBundle mainBundle]

У меня есть код, который вызывает [NSBundle mainBundle] в какой-то момент, главным образом, для чтения / установки предпочтений. Когда я тестирую модуль методом, тест завершается неудачно, потому что mainBundle теста не содержит файл.

Это известная проблема, которую Apple не исправит, поскольку считает, что это не ошибка:

Суть их ответа в том, что XCTest работает правильно, возвращая свой собственный основной пакет вместо пакета цели теста.

Ранее наша кодовая база использовала переопределение категории на NSBundle"s +mainBundle метод класса, чтобы обойти это. Но это опасно, потому что поведение переопределения существующего метода в категории не определено.

Если имя метода, объявленного в категории, совпадает с именем метода в исходном классе или методом в другой категории того же класса (или даже суперкласса), поведение не определено относительно того, какая реализация метода используется в во время выполнения.

На самом деле Xcode предупреждает вас об этом:

Категория реализует метод, который также будет реализован его основным классом

Итак, каков правильный метод решения проблемы?

1 ответ

Решение

Самый простой и понятный способ решения этой проблемы - частичная насмешка над классом 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

Красиво и чисто.

[ Источник]

Другие вопросы по тегам