2015-08-26 6 views
2

Я использую RestKit в своем приложении, настроив его в AppDelegate. У меня есть некоторые модульные тесты, которые зависят от синглета RKObjectManager. Это настроено в AppDelegate. Некоторые тесты настраивали хранилище управляемых объектов специально для тестов, как показано ниже. Другие звонят getObject и т. Д. Непосредственно на него, чтобы проверить сопоставления ответов.Класс загружается из разных NSBundle в тестах после обновления драгоценного камня Cocoapods, в результате чего nil singleton

Это в моем тесте setUp:

RKObjectManager *mgr = [RKObjectManager sharedManager]; 
[mgr setManagedObjectStore:managedObjectStore]; 

Это успешно работает в течение длительного времени.

Я недавно обновил свой Cocoapods камень от 0.33.1 до последней (0.38.2 прямо сейчас), и теперь, в приведенном выше примере mgr является nil. Если я бросаю контрольную точку на второй линии выше, sharedManager явно возвращает значение не-ноль, но моя локальная переменная равна нулю:

(lldb) po mgr 
nil 
(lldb) po [RKObjectManager sharedManager] 
<RKObjectManager: 0x7fe9e2d1d5e0> 

Я подозреваю, что я, по сути, две копии RKObjectManager подгружается во время выполнения (один раз из пакета приложений и один раз из тестового пакета). У меня есть tried all the solutions listed here, но интересный комментарий talks about how each target gets its own copy of the class. Действительно, если я переопределяю метод +(void) load на RKObjectManager, он вызывается дважды.

Если я сохраняю ссылку на общий менеджер в качестве свойства в своем AppDelegate, то я могу извлечь из него общий экземпляр - просто не из метода класса, как указано выше. Я бы предпочел не повторять эту работу во всех моих тестах.

Как настроить Cocoapods, чтобы связать «правую» версию RKObjectManager с моими тестами, чтобы я мог снова получить общий экземпляр?

Мой podfile:

platform :ios, '8.0' 

target 'Closeout' do 
    pod 'RestKit' 
    ... some other pods 
end 

target 'CloseoutTests' do 
    pod 'RestKit/Testing' 
    pod 'OHHTTPStubs' 
end 

Edit: У меня есть обходной путь, который, безусловно, лучше, чем разоблачение собственность на AppDelegate просто в пользу тестирования, но я все же хотел бы знать, как избежать этого :

AppDelegate* delegate = (AppDelegate*)([UIApplication sharedApplication].delegate); 
NSBundle *appBundle = [NSBundle bundleForClass:[delegate class]]; 
id objMgr = [appBundle classNamed:@"RKObjectManager"]; 
[[objMgr sharedManager] setManagedObjectStore:managedObjectStore]; 

ответ

0

CocoaPods изменил способ зависимости добавляются в версии 0.36 - the release blog has a very good explanation of why this is necessary, но общая идея состоит в том, что она была необходима для Swift поддержки.

Я добавил следующее ключевое слово, введенное в CocoaPods 0,36 моему Podfile:

use_frameworks!

я снял цели и используется link_with вместо этого, так что мой Podfile выглядит следующим образом:

platform :ios, '8.0' 

link_with 'Closeout', 'CloseoutTests' 
use_frameworks! 

pod 'RestKit' 
pod 'RestKit/Testing' 
pod 'OHHTTPStubs' 
... other pods 

Кроме того, я должен был убедиться, что я запускал RestKit 0.25 или выше, так как это includes this PR, что позволяет поддерживать Framework.

pod 'RestKit', '0.25.0'

Наконец, я должен был исправить кучу ошибок компиляции:

#import <RestKit.h> стал #import <RestKit/RestKit.h>