Max*_*lle 15 unit-testing core-data ios xctest
我试图通过使用XCTest类和方法在Xcode 5中对我的模型进行单元测试.
因为我的模型类继承managedObject,我不能只是实例化(alloc/init)它们并调用getter和setter或我需要测试的方法.我需要使用NSEntityDescription和创建它们并使用a managedObjectContext.
就这一点而言,我遇到了麻烦.我不知道在哪里以及如何创建managedObjectContext用于单元测试的目的.
如果有人有一些建议或代码示例,那将非常有帮助.谢谢.
Abi*_*ern 12
我使用内存存储来进行单元测试并在其中创建所有实体.
这个类方法可以放在 TestsHelper.m
+ (NSManagedObjectContext *)managedObjectContextForTests {
static NSManagedObjectModel *model = nil;
if (!model) {
model = [NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]];
}
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSPersistentStore *store = [psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:nil];
NSAssert(store, @"Should have a store by now");
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
moc.persistentStoreCoordinator = psc;
return moc;
}
Run Code Online (Sandbox Code Playgroud)
这对我有用,因为我使用依赖注入来传递我的moc而不是使用单例.
cti*_*tze 12
我同意@Abizern:NSManagedObjectContext在您的代码中将实例传递给周围,而不是依赖于您的应用委托,全局变量或自定义帮助单例.
如果您知道某些控制器需要访问权限,请NSManagedObjectContext在其init方法中添加一个参数并保留对它的强引用:
@interface SomeController : NSObject
@property (nonatomic, strong, readwrite) NSManagedObjectContext *context;
- (instancetype)initWithContext:(NSManagedObjectContext *)context;
@end
Run Code Online (Sandbox Code Playgroud)
这是进行"依赖注入"的最低要求.您不需要花哨的框架来为您进行注射.相反,在您的应用程序中,您可以分配NSManagedObjectContext可能使用SQLite存储的常用实例.在测试中,您NSManagedObjectContext使用内存存储创建一个单独的存储并将其传递给SomeController.这甚至适用于使用OCMock的(部分)模拟.
在objc.io#4中有一些很好的例子,特别是Chris Eidhof的示例应用程序:http://www.objc.io/issue-4/full-core-data-application.html
查看GitHub上的objc.io示例代码,您将看到一个PersistentStack帮助程序类,它负责初始化应用程序的托管对象上下文.Chris使用抽象测试用例子类来提供测试上下文.
总体方针是这样的:
NSManagedObjectContext在适当的时候准备一次.传递托管对象并使用托管对象来访问上下文.Florian Kugler用这种方式说:
托管对象应该在应用程序中传递,至少跨越模型 - 控制器障碍,甚至可能跨越控制器视图障碍.后者在某种程度上更具争议性,并且可以通过例如定义对象必须符合的协议以便被某个视图使用,或者通过在视图类别中实现配置方法来弥补差距,从而以更好的方式进行抽象.从模型对象到视图的细节.
无论如何,我们不应该将托管对象限制到模型层,并且只要我们想要传递它们就将它们的数据拉出到不同的结构中.托管对象是Core Data应用程序中的一等公民,我们应该相应地使用它们.例如,应在视图控制器之间传递托管对象,以便为它们提供所需的数据.
为了访问托管对象上下文,我们经常在视图控制器中看到这样的代码:
Run Code Online (Sandbox Code Playgroud)NSManagedObjectContext *context = [(MyApplicationDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];如果您已将模型对象传递给视图控制器,则通过此对象直接访问上下文会更好:
Run Code Online (Sandbox Code Playgroud)NSManagedObjectContext *context = self.myObject.managedObjectContext;这消除了对应用程序委托的隐藏依赖性,并使其更易读,也更容易测试.
这是我得到的最好的整体建议.现在我可以在需要的地方测试核心数据的使用情况.以前,通过全局单例类(自定义类或应用程序委托)访问上下文在生产中使用很方便,但在测试中证明很难验证.