【问题标题】:iOS Application Unit Testing with Core Data, and Magical Record使用 Core Data 和 Magical Record 进行 iOS 应用程序单元测试
【发布时间】:2013-07-09 04:10:08
【问题描述】:

我有一个 iOS 应用程序,它使用 Core Data 和出色的 Magical Record 来管理持久性。这是我的问题:

我们现有的单元测试结构使用标准的 iOS 应用程序测试。我想为每个测试使用一个干净的内存数据库来运行我的单元测试。我按照this article 中的说明使用 Magical Record 进行设置。该问题出现在运行应用程序测试的实现中。因为应用程序测试首先运行应用程序包,然后是单元测试包,所以在我的内存存储调用有机会运行之前调用了我设置核心数据堆栈的正常调用。

我用谷歌搜索了这个问题一整夜,发现了几篇很有希望的文章:

这些问题在于它们使用单​​例数据访问对象作为进入其核心数据调用的网关。我的应用程序不是这样设置的。我正在使用对 Magical Record 的调用来获取和保存数据。

有人遇到过这个问题吗?如果是这样,我是否遗漏了一些细节,这些细节可以让我在测试运行时将数据设置交换到内存存储中?

编辑:添加代码

在我的应用委托中,我有这个:

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    [MagicalRecord setupAutoMigratingCoreDataStack];
    // Other setup code
    return YES;
}

在每个处理核心数据的单元测试类中,我都有这个:

-(void)setUp{
    [super setUp];
    [MagicalRecord setDefaultModelFromClass:[self class]];
    [MagicalRecord setupCoreDataStackWithInMemoryStore];
}

-(void)tearDown{
    [MagicalRecord cleanUp];
    [super tearDown];
}

我可以看到每个测试都调用了应用程序委托代码和设置/拆卸,但我不确定如何使测试的默认核心数据堆栈使用内存存储。我还将 .xcdatamodel 文件添加到单元测试目标中。

【问题讨论】:

  • 您是否有一些示例代码或项目设置可以帮助缩小范围?我认为您缺少一件事,但是如果没有看到您在做什么,我不知道它是什么。
  • @casademora - 添加了代码来说明我是如何做事的。我也使用 CocoaPods 来拉入 Magical Record,不确定这是否与问题有关。
  • hrm,您需要运行应用程序测试吗?在这种情况下,您不需要使用测试设置。如果您正在使用逻辑测试,那么博客文章中指定的设置可以正常工作。另外,我讨厌应用程序和逻辑测试之间存在区别:/
  • @casamedora 关于应用程序测试的要点。我试图在这方面走阻力最小的道路,但我可能不得不硬着头皮向项目添加逻辑测试。感谢您的意见!
  • @MarkStruzinski 您最终是否进行了逻辑测试?我自己也遇到过这个问题...

标签: ios core-data ocunit magicalrecord


【解决方案1】:

如果我正确理解您的问题,问题是即使在 setUp 中调用 [MagicalRecord setupCoreDataStackWithInMemoryStore]; 后,测试仍在访问真实数据存储?

我在为负责数据库交互的对象编写单元测试时遇到了同样的问题,并且几乎没有调试,我想我发现了一个问题。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 中的[MagicalRecord setupAutoMigratingCoreDataStack]; 早于setUp 中的[MagicalRecord setupCoreDataStackWithInMemoryStore]; 被调用。如果我们看看 MagicalRecord 创建核心数据堆栈的实际工作原理,我们就会明白问题出在哪里。

+ (void) setupCoreDataStackWithInMemoryStore;
{
    if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return;

    NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithInMemoryStore];
    [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];

    [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];
}

[NSPersistentStoreCoordinator MR_defaultStoreCoordinator] 在设置内存存储时不为零,这使得上述方法无需执行任何操作即可静默返回。到那时,您将得到真正的数据存储,而不是内存存储。解决方法很简单。只需拨打电话

[MagicalRecord cleanUp];

setUp 中调用[MagicalRecord setupCoreDataStackWithInMemoryStore]; 以撕裂当前数据堆栈并真正设置内存存储之前,它应该如下所示:

- (void)setUp{
    [super setUp];
    [MagicalRecord setDefaultModelFromClass:[self class]];
    [MagicalRecord cleanUp];
    [MagicalRecord setupCoreDataStackWithInMemoryStore];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 2014-09-27
    • 2012-12-15
    • 2016-01-02
    • 2013-07-22
    • 2011-08-04
    • 1970-01-01
    相关资源
    最近更新 更多