如何在测试之间重置Realm的状态?

时间:2016-02-27 00:02:32

标签: realm realm-cocoa

我们一直在使用RLMClearRealmCache来清除测试迁移的测试之间的Realm状态。如果未清除缓存,则下一个测试将不会执行迁移,因为即使我们已删除并替换了realm fixture文件(具有旧架构),缓存仍会报告架构是最新的。

RLMClearRealmCache最近被移到了Objective-C ++文件中,所以我们想停止使用它并避免在我们的项目中使用Objective-C ++。这仍然是最佳/唯一的方式吗?

很明显,我们没有在内存领域使用这些规范。我们从特定版本的设备中保存了default.realm fixture文件,我们正在执行以下操作:

- (void)loadBundledRealmWithName:(NSString *)name;
{
    [self deleteOnDiskRealm];

    // copy over the file to the location
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *source = [[NSBundle bundleForClass:[self class]] pathForResource:name ofType:@"realm"];
    if (documentsDirectory && source) {
        NSString *destination = [documentsDirectory stringByAppendingPathComponent:kDefaultRealmFileName];
        [[NSFileManager defaultManager] copyItemAtPath:source toPath:destination error:nil];
    }
}

但是,在测试用例之间,没有调用RLMClearRealmCache,似乎Realm的缓存确定已经运行了迁移,即使我们已经换出.realm文件并且他们需要再次运行。

2 个答案:

答案 0 :(得分:2)

您可以为每个测试使用单独的内存Realm。当你这样做时,每个测试都会获得一个“新鲜”的Realm,并且Realm的状态不会从一个测试泄漏到另一个测试。

要实现这一点,请在运行之前将Realm的配置inMemoryIdentifer设置为当前测试的名称。您可以在XCTestCase子类setUp方法中执行此操作(如Realm文档中所述):

override func setUp() {
    super.setUp()
    Realm.Configuration.defaultConfiguration.inMemoryIdentifier = self.name
}

修改

这个答案不符合更新后的问题,但无论如何我都会留在这里,因为它可能会帮助其他人在测试之间寻找重置Realm状态的方法。

答案 1 :(得分:0)

我们最终通过利用它将在不再引用的情况下这样做来让Realm清除其缓存。跟踪停止这样做的问题有点棘手:我们在测试运行之间保留了对Realm对象的引用:

context(@"some context", ^{
    __block MyRealmObject *whoops;

    beforeEach(^{
        [specHelper loadBundledRealmWithName:@"release-50-fixture.realm"];
        [migrationManager performMigrations];
        whoops = [[MyRealmObject allObjects] firstObject];
    });

    it(@"first", ^{
        // migrations will run for this `it`
    });

    it(@"second", ^{
        // migrations will NOT run for this `it` since the old Realm is still around and its cache thinks migrations have already run (even though we've swapped out the backing DB).
        // the issue is that `whoops` is retaining a `MyRealmObject` and thus the Realm.
    });
});