Class 在更新 Cocoapods gem 后的测试中似乎是从不同的 NSBundle 加载的,导致 nil 单例
Class appears to be loaded from different NSBundle in tests after updating Cocoapods gem, resulting in nil singleton
我在我的应用程序中使用 RestKit,在 AppDelegate 中设置它。我有一些依赖于 RKObjectManager
单例的单元测试。这是在 AppDelegate 中设置的。一些测试专门为测试设置了一个托管对象存储,如下所示。其他人直接调用 getObject
等来测试响应映射。
这是我的测试setUp
:
RKObjectManager *mgr = [RKObjectManager sharedManager];
[mgr setManagedObjectStore:managedObjectStore];
这已经成功运行了很长时间。
我最近将我的 Cocoapods gem 从 0.33.1
更新到最新版本(现在 0.38.2
),现在,在上面的例子中 mgr
是 nil
.如果我在上面的第二行放置一个断点,sharedManager
显然 returns 一个非 nil 值,但我的局部变量是 nil:
(lldb) po mgr
nil
(lldb) po [RKObjectManager sharedManager]
<RKObjectManager: 0x7fe9e2d1d5e0>
我怀疑我实际上在运行时加载了两个 RKObjectManager
副本(一次来自应用程序包,一次来自测试包)。我 tried all the solutions listed here, but the comment of interest talks about how each target gets its own copy of the class。实际上,如果我重写 RKObjectManager
上的 +(void) load
方法,它会被调用两次。
如果我将对共享管理器的引用作为 属性 存储在我的 AppDelegate 上,那么我可以从中成功检索共享实例 - 而不是从上面的 class 方法中检索。我不想在我所有的测试中重复这个解决方法。
如何通过测试将 Cocoapods 配置为 link "right" 版本的 RKObjectManager,以便我可以再次直接检索共享实例?
我的播客文件:
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 版中更改了添加依赖项的方式 - the release blog has a very good explanation of why this is necessary,但总体思路是 Swift 支持需要它。
我在我的 Podfile 中添加了在 CocoaPods 0.36 中引入的以下关键字:
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,启用对框架的支持。
pod 'RestKit', '0.25.0'
最后,我不得不修复一堆编译错误:
#import <RestKit.h>
变成了#import <RestKit/RestKit.h>
我在我的应用程序中使用 RestKit,在 AppDelegate 中设置它。我有一些依赖于 RKObjectManager
单例的单元测试。这是在 AppDelegate 中设置的。一些测试专门为测试设置了一个托管对象存储,如下所示。其他人直接调用 getObject
等来测试响应映射。
这是我的测试setUp
:
RKObjectManager *mgr = [RKObjectManager sharedManager];
[mgr setManagedObjectStore:managedObjectStore];
这已经成功运行了很长时间。
我最近将我的 Cocoapods gem 从 0.33.1
更新到最新版本(现在 0.38.2
),现在,在上面的例子中 mgr
是 nil
.如果我在上面的第二行放置一个断点,sharedManager
显然 returns 一个非 nil 值,但我的局部变量是 nil:
(lldb) po mgr
nil
(lldb) po [RKObjectManager sharedManager]
<RKObjectManager: 0x7fe9e2d1d5e0>
我怀疑我实际上在运行时加载了两个 RKObjectManager
副本(一次来自应用程序包,一次来自测试包)。我 tried all the solutions listed here, but the comment of interest talks about how each target gets its own copy of the class。实际上,如果我重写 RKObjectManager
上的 +(void) load
方法,它会被调用两次。
如果我将对共享管理器的引用作为 属性 存储在我的 AppDelegate 上,那么我可以从中成功检索共享实例 - 而不是从上面的 class 方法中检索。我不想在我所有的测试中重复这个解决方法。
如何通过测试将 Cocoapods 配置为 link "right" 版本的 RKObjectManager,以便我可以再次直接检索共享实例?
我的播客文件:
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 版中更改了添加依赖项的方式 - the release blog has a very good explanation of why this is necessary,但总体思路是 Swift 支持需要它。
我在我的 Podfile 中添加了在 CocoaPods 0.36 中引入的以下关键字:
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,启用对框架的支持。
pod 'RestKit', '0.25.0'
最后,我不得不修复一堆编译错误:
#import <RestKit.h>
变成了#import <RestKit/RestKit.h>