Android: Testing Realm
Realm is a super convenient mobile database technology with many features. It may significantly simplify data persistence, and since the introduction of Realm Mobile Platform also data exchange, in Android. Thanks to its auto-updating objects it could also make data change propagation on UI level an ease.
Since Realm has the potential to become a crucial part of your application it is very important to know how to test it! There is an official approach for unit testing Realm on Android but there is another, IMHO simpler approach.
This short article describes an alternative approach to test data persistence with Realm in Android.
When searching for “Testing Realm” you’ll most probably find the quite comprehensive official unit text example by Realm. It’s well documented and may be the perfect starting point for you.
However, we decided not to use this approach for the following reasons:
- Although the actual test code covers only a few lines, you’ll need a few hundred more lines to setup the test. This prevents a good readability and maintainability of the actual test code.
- It’s required to know some of Realm’s internal implementation details which then need to be mocked. This may lead to big adaptation efforts when the internal implementation changes (which I’ve seen a couple of times already)
Therefore we are using a different approach which I’d like to present you in the consecutive section.
But please keep in mind that this is only another idea how to do it with its own advantages and disadvantages and it can co-exist with the official approach.
Instead of putting a lot of effort in mocking a lot of things, we are simply using a real Realm implementation and the following idea:
Don’t test Realm!
Test the business logic which relies on Realm!
To do so, we are making use of Realm’s in-memory database feature by constructing a Realm like this:
RealmConfiguration testConfig =
Realm testRealm = Realm.getInstance(testConfig);
We then inject this special Realm into our business logic classes. To test a certain use case we could:
- prepare the special Realm with the expected data to load or
- verify if our code writes correct data to Realm:
//0. inject the prepared Realm
MyBusinessLogic interactor = new MyBusinessLogic(testRealm);
//1.1 write expected data
//1.2 assert that business logic loads correct data
MyBusinessEntity actualData = interactor.loadBusinessStuff();
//2.1 write actual data
//2.2 assert that business logic writes correct data
actualData = testRealm.where(MyBusinessEntity.class).findAll();
Since Realm (Java) is only running on Android, the test needs to be executed on a real or virtual Android device. Plain JVM tests won’t work. The only thing required for this is to copy the test class to the androidTest directory, so it’ll get picked up for connected checks automatically.
That’s pretty much it. Here’s example code which demonstrates the approach in detail.
There is a known issue using this approach. When your RealmModels have public fields and you try to executed Android connected checks, you’ll get a CannotCompileException. To come around this, you need to replace public fields by getters/setters.
This article demonstrated an alternative approach to test Realm on Android. It relies on Realm’s in-memory feature and Android’s connected checks. Instead of having to mock a lot of things tests are focused on the actual business logic. On the one hand test execution is expected to be a bit slower than plain JVM tests. On the other hand tests become more readable, reliable and maintainable. This approach is non-exclusive and can be used together with the official approach.