AppEngine unit testing made easy With JUnit Rules
Hello there! If you are using AppEngine for hosting your application, then you will be using one or more of their infrastructure services like Datastore, Memcache, TaskQueues, UserService, etc.
And you will be needing to write unit tests to make sure your application functionality is working as expected with these services. For that, you need to set up some configurations to test these services in your local environment.
If you are new to AppEngine service testing, then Google has great documentation on how to set up this configuration with sample codes. Take a look at Local Unit Testing for Java.
For example, here is a sample code from Google to perform datastore testing:
This is great. But unfortunately most of the time, our application will be making use of multiple AppEngine services like Memcache for the entity (Objectify) caching, TaskQueues for queueing asynchronous tasks, etc. The real pain point comes when we try to add a test case for a code that uses more than one of these services, because of the multiple configurations.
Okay, that’s the lot of configuration, but guess what — it’s not all. What if you need to change specific settings for some tests like High Replication, Queue XML Path, or Current User? Then your set up will be even more complex. And you need to repeat all these for each of your unit test classes.
Oh, by the way, did you forgot the Objectify test setup? Take a look at Objectify Unit Testing.
You might be thinking,
“Let’s set up all of these configurations in the parent class and every unit testing class will extend this one”
We can do that, but there is another problem with it:
Each of these services is expensive to create. You need to configure the environment using only the services you need.
So unnecessarily configuring all services will probably slow down the test execution time.
Okay, is there a rescuer?
Yes, Junit Rules comes to the rescue!
“Rules allow very flexible addition or redefinition of the behavior of each test method in a test class. Testers can reuse or extend one of the provided Rules below, or write their own”
There are so many great articles out there about Junit Rules — please check them out.
So with JUnit rules, we are able to set up external dependencies before test execution in an easy way. With a few tweaks, we can setup AppEngine related services per class in the way we wanted. Here is a sample:
Here AppEngineRule is a simple class that extends ExternalResource and was created using a builder pattern. We can set up services which we need, and if you see in the SampleTestClass, we can do all the setup in one line.
@Rule
public final AppEngineRule rule = AppEngineRule.builder()
.withDatastore()
.withQueue()
.build();
And AppEngineRule class overrides before
and after
methods to set up AppEngine setup and tearDown functionalities. You can also configure similarly for each Test class with only the required services.
Is that all? Can we do any better?
Of course, we can! To make this setup easy you need to write something similar to AppEngineRule class with all the boilerplate setup code.
Here is good news: you don’t need to write any. I made a small library with all the necessary setup implementation for all the services and with even more configurable options.
In your build script, simply add the dependency, for example in Gradle:
testCompile 'com.github.ramesh-dev:gae-test-util-java:0.3'
With this, we can have flexible configurations like the following:
Conclusion
So Junit Rules is a handy option to easily configure our external dependencies, even for complex ones like AppEngine services. You can also have other Rules and chain them in a specific order using Rule Chain
Thank you for reading and this time, and Happy Testing…