by Ramesh Lingappa
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 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, 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. Most of the time, our services will be making use of multiple AppEngine services like Memcache for entities (Objectify), queueing tasks after saving an entity. The real pain point comes when we try to set up 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 test 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.
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 setup 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
after methods to setup AppEngine setup and tearDown functionalities. You can also configure similarly for each Test classes 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:
With this, we can have flexible configurations like the following:
So Junit Rules is a handy option to easily configure our external dependencies, even for complex one 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…