Testing is an integral part of modern software development. It gives you a guarantee that your code works up to specification and provides fast automated regression for refactorings and changes to the code. Tests also function as living documentation for a codebase by describing exactly how the resulting application or API is supposed to function and how different constraints may change its behavior. Perhaps most importantly, it does so in a way the developer can understand in the context of the code instead of abstract requirements that may be open to interpretation.
However, this doesn’t mean that tests have to be rigid and difficult to read. To illustrate this. Let’s look at a simple JUnit test case that uses a few common assertions
While it’s quite straightforward for someone familiar with the framework, we can do better by taking advantage of a more natural assertions API. For example, wouldn’t it be much more natural to write something such as,
This is where assertk comes in. assertk is a fluent assertions library inspired by AssertJ. It aims to help you write richer more expressive tests. In this article, we’ll take a look at how assertk can help you improve the readability of your test cases as well as make assertions on complex objects and collections easier.
Getting started
Setting up assertk is simple. It’s hosted on Maven Central, so you can grab it using your favorite build tool or package manager. For example, you could add it to your test configuration using gradle like so
At this point, you should now be able to use assertk in your tests. Let’s take a look at a couple of simple test cases to get familiar with it. Assuming we have a relatively simple data class,
We can make assertions on its properties using the assert() function.
You can make multiple assertions on the same property by using a lambda.
Collections Assertions
Making assertions on collections can get pretty tricky sometimes. However, assertk comes with a lot of handy functions to make this easy. Let’s take a look at some of these in action.
You can check to see if your list contains a list of elements in any order using containsAll.
containsExactly asserts that your list contains only the given elements in exactly the same order.
Finally, containsNone asserts that your list does not contain any of the given items.
It’s also really easy to make assertions on specific items in your list using index.
Maps have similarly fluent assertions.
Maps you can also make an assertion on a value which corresponds to a given key using the key accessor.
Property assertions
You can also make assertions to validate a specific property in a class using the prop function.
Or you can compare multiple properties between objects using isEqualToWithGivenProperties. For example, Let’s compare a few fields between two person objects
This assertion would pass because only the name properties and email properties would be compared.
Custom Assertions
To get an even higher degree of expressiveness and flexibility in your tests, you can add your own custom assertions. assertk relies heavily on extension functions as part of its public API. This makes it really easy to add your own custom assertions. Let’s add a few custom assertion to the Person class from earlier.
Assert exposes a property called actual which is the value under test. You can validate that it is correct using whatever custom logic you have available and then return if it’s correct. In the event of a failure, you should invoke the expected function with an error message to fail the test.
And that’s it! Nothing to extend or implement. Just a single function in our test which we can use just like we would any other function in the API.
Conclusion
assertk makes writing tests a lot easier with its fluent API. It’s really easy to extend to make your tests a lot more readable. For more samples and usages on all of the APIs, I recommend looking into the test sources. We also welcome your feedback and feature requests on the APIs.