在更新Cocoapods gem后的测试中,类似乎是从不同的NSBundle中加载的,导致nil单例



我在应用程序中使用RestKit,在AppDelegate中设置它。我有一些依赖于RKObjectManager单例的单元测试。这是在AppDelegate中设置的。一些测试专门为测试设置托管对象存储,如下所示。其他人则直接调用getObject等来测试响应映射。

这是我的测试setUp:

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

这已经成功工作很长时间了。

我最近更新了我的Cocoapods宝石从0.33.1到最新的(0.38.2现在),现在,在上面的例子中,mgrnil。如果我在上面的第二行删除一个断点,sharedManager显然返回一个非nil值,但我的局部变量是nil:

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

我怀疑我在运行时有效地加载了两个RKObjectManager副本(一次来自应用程序包,一次来自测试包)。我已经尝试了这里列出的所有解决方案,但感兴趣的评论讨论了每个目标如何获得自己的类副本。实际上,如果我在RKObjectManager上重写+(void) load方法,它将被调用两次。

如果我将对共享管理器的引用作为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

编辑:我有一个解决方案,这当然比在AppDelegate上暴露一个属性更好,只是为了测试的好处,但我仍然想知道如何避免这样做:

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

CocoaPods在0.36版本中改变了依赖项的添加方式——发布博客很好地解释了为什么这是必要的,但总的想法是,这是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或更高版本,因为它包括这个PR,使支持框架。

pod 'RestKit', '0.25.0'

最后,我必须修复一堆编译错误:

#import <RestKit.h>变为#import <RestKit/RestKit.h>

最新更新