We've been using RLMClearRealmCache
to clear Realm's state between tests that are testing migrations. If the cache is not cleared, the next test will not perform migrations, since the cache still reports the schema being up to date, even though we've deleted and replaced realm fixture file (which has an old schema).
RLMClearRealmCache
was moved to an Objective-C++ file recently, so we want to stop using it and avoid using Objective-C++ in our project. Is this still the best/only way of doing it?
To be clear, we are not using in-memory Realm for these specs. We have a default.realm
fixture file we've saved from a device at a specific release and we're doing the following to use it:
- (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];
}
}
However, between test cases, without a call to RLMClearRealmCache
, it seems as though Realm's cache determines that migrations have already been run, even though we've swapped out the .realm
file and they need to be run again.
We ended up getting Realm to clear its cache by leveraging the fact that it will do so if it is no longer referenced. It was just a bit tricky to track down the issue stopping it from doing so: we were retaining a reference to a Realm object between test runs:
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.
});
});