Java Unit Testing Niceness

With this blog I just want to share some tips on how to use two interesting test frameworks that are not very well known, Komarro and Catch Exception.

Class Under Test

The following class is a (modified) example of an anti-corruption layer used in a project I’m working on. It uses an instance of MappingRepository that is a part of another bounded context to obfuscate EntityId's (which in the real project is called something else).

Happy Flow Test

So let’s see how simple it is to use Komarro to test the happy flow of this simple class. First off all let’s create a JUnit before method that initializes the EntityIdObfuscationService instance that we’ll use in the test:

The instanceForTesting method is a part of the Komarro API and is used to create an instance of the class under test and create and inject mocks automatically into the created instance. This means that it’ll create a mock for the MappingRepository automatically since it’s annotated with Inject in the EntityIdObfuscationService instance. We also create an instance of Mapping that we’ll used in the test:

Now that we’ve prepared the class under test let’s take a look at the actual test:

Instead of setting up expectations for a collaborator Komarro allows us to setup expectations for what’s returned by the collaborator. In this case the collaborator is the mappingRepository which returns an instance of Mapping. This means that the given statement tells Komarro that for any collaborator that happen to return a Mapping class it should return the mapping instance we created in the given_mapping_is_initialized method. This is pretty cool since now we could actually use a completely different collaborator with a different method name and the test would still pass without any change as long as the new collaborator method returns a Mapping instance.

Exception Flow

There are several ways to test for expected exceptions in a test. You could wrap the tested method in a try-catch statement, add an expected statement in the @Test annotation or use the ExpectedException JUnit rule. None of these approaches are perfect though. Using “try-catch” is verbose and doesn’t follow the BDD given-when-then paradigm. Using @Test(expected = IllegalArgumentException.class) doesn’t allow you to further inspect the exception such as validating the error message. Neither does it follow the given-when-then paradigm. Using the ExpectedException rule makes the test look a little awkward since you have to define your expected exception before the exception has happened and this too “violates” the given-when-then paradigm. But here the Catch Exception framework can help. Let’s look at the test:

The catch exception framework provides us with the when and then methods that we’ve statically imported in this example. What happens is that we wrap the instance that that contain the method we expect to throw an exception in the when method. The framework will return a proxy of the instance and we invoke the method that we expect to throw the exception. Catch Exception will now catch the exception and store it away for later retrieval. We retrieve the caught exception by calling the then(caughtException()) method. It’ll return a small assertion API similar to fest-assert that we can use to verify the caught exception. The test now reads really nice and follows the given-when-then paradigm.

Komarro and Catch Exception are nice contributions to everyones unit testing tool-suite in Java. There are cases when Komarro doesn’t work well, for example if you have two collaborators that returns different instances of the same type. Also catch exception won’t work well for static methods. But regardless they are worth looking into!

Here’s the full code including imports:

Leave a Reply

Close Menu