8

I have an application for Android where I use Realm to persist data. I now want to write a unit test for this application, utilizing Realm.

However, I do not want the unit test to interfere with my existing Realm data. So I want to generate different Realm files for my test Instance. I don't care if they have a different name, or are stored in a different directory.

I have tried to use a RenamingDelegatingContext, but with no success. According to https://groups.google.com/forum/#!msg/realm-java/WyHJHLOqK2c/WJFYvglIGk0J getInstance() only uses the Context to call getFilesDir(), which does not seem to be overwriting the getFilesDir() method, so I end up using my live data for testing.

Next I tried to use IsolatedContext, but IsolatedContext.getFilesDir() returns null, so this also was not successful.

Finally, I tried to write a class extending RenamingDelegatingContext, overwriting getFilesDir(), return a different directory for Realm to use. I created the directory using the DeviceMonitor of AndroidStudio, but when I try to use this context, Realm fails with an io.realm.exceptions.RealmIOException: Failed to open . Permission denied. open() failed: Permission denied.

Does anyone know if there is a possibility to test Realm without affecting live data?

serv-inc
  • 35,772
  • 9
  • 166
  • 188
Benjamin Scharbau
  • 2,028
  • 1
  • 16
  • 33

3 Answers3

9

I was actually quite blind, with the solution being quite easy by just using a different name for the RealmDatabase during test setup while generating its configuration. My solution now looks as follows:

RealmConfiguration config = new RealmConfiguration.Builder(getContext()).
        schemaVersion(1).
        migration(new CustomMigration()).
        name("test.realm").
        inMemory().
        build();
Realm.setDefaultConfiguration(config);
serv-inc
  • 35,772
  • 9
  • 166
  • 188
Benjamin Scharbau
  • 2,028
  • 1
  • 16
  • 33
8

If you are using JUnit4 you can use the TemporaryFolder rule to generate a test folder: https://garygregory.wordpress.com/2010/01/20/junit-tip-use-rules-to-manage-temporary-files-and-folders/

@Rule
public TemporaryFolder testFolder = new TemporaryFolder();

@Test
public void testRealm() throws IOException {
    File tempFolder = testFolder.newFolder("realmdata");
    RealmConfiguration config = new RealmConfiguration.Builder(tempFolder).build();

    Realm realm = Realm.getInstance(config);
    // Do test
    realm.close(); // Important
}
Christian Melchior
  • 19,978
  • 5
  • 62
  • 53
  • I'm currently using JUnit3, so this does not seem usable for me. I solved my issue by using a different database file with the ConfigurationBuilder, but I will keep your solution in mind, since it seems actually a little bit better because it also deletes the temporary files after testing – Benjamin Scharbau Dec 15 '15 at 03:44
  • 1
    @Christian Tried above code with Junit4 getting following exception on getInstance() : java.lang.UnsatisfiedLinkError: no realm-jni in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at io.realm.internal.RealmCore.loadLibrary(RealmCore.java:117) – GaneshP Mar 03 '16 at 11:11
  • 1
    Currently Realm does not support testing on the JVM, you need to run the tests on a device. – Christian Melchior Mar 03 '16 at 11:13
  • is there any better way to write unit test for realm queries , other than mocking response of every small function ?? – GaneshP Mar 03 '16 at 11:15
  • @ChristianMelchior can you explain me please what's the difference between usage of temporary folder rule and setting realm instance as inMemory in this case – Mike Herasimov Mar 05 '17 at 16:55
2

A minor alternative to using setDefaultConfiguration might be to directly use Realm.getInstance in @BeforeClass:

RealmConfiguration testConfig = 
   new RealmConfiguration.Builder().
      inMemory().
      name("test-realm").build();

Realm testRealm = Realm.getInstance(testConfig);

and inject the testRealm into your classes.

serv-inc
  • 35,772
  • 9
  • 166
  • 188