Today I’d like to share with you a very interesting concept in software testing – Assert Object pattern. It makes the Assert part of a test much simpler and more readable. Let’s dive right into it 😉
The Asserts Hell
Let’s consider the following unit test:
What’s wrong here? Given and When sections are great single-liners. We know straightaway what’s the input and the action executed. However, Then block is too complex. It’s hard to figure out, just passing quickly through this test, what is expected. This case is even not that bad thanks to the usage of FluentAssertions.
I spend a lot of time writing tests (unit or integration), but I spend even more time reading them. I always hope that I will find these idyllic tests that act as code documentation… 🧐
However, let’s go step by step. I recently took place in a software testing course. That’s where I discovered the solution to The Asserts Hell.
Assert Object for Better Asserts
Assert Object pattern is what solves our problem. The idea is to create an Assert class which wraps the original object being tested. In our case the tested object is of Product class, so our assert class will be called ProductAssert.
Let’s see the implementation:
As you can see, we simply moved the asserts from our test’s Then section into ProductAssert class’s methods. Additionally, we always return this from each asserting method, which allows chaining functions calls.
We can now use such assert object in our unit test:
You must agree it’s much more readable now 😉
We can of course improve it even more, for example by wrapping these 3 assertion methods (BeAvailable(), HaveDiscount() and Cost()) into a single one. We can also easily create an extension method for the Product class itself, so the assert object doesn’t have to be instantiated in our unit test. I could even add an extension to FluentAssertions library.
You can find complete source code used as examples in this article here.
Assert Object – summary
I personally find Assert Object a very useful tests code refactoring method. As a programmer, you spend most of your time not on writing, but on reading the source code. Clear and simple tests can make your (and your colleagues’) life much better 😉
Of course, the Assert Object pattern should not be your default way of asserting. If you can complete your test with one or two assertions, then it’s probably better to keep it without wrapping into any additional objects. Having too many assert statements might also mean that the objects being tested are poorly designed. However, as we often work with legacy code which we can’t easily change or refactor, it might be a good solution.
What patterns for writing better tests do you use? Share your tips in the comments!