Loading
Most of the effort in unit testing comes from maintaining your tests over time. So how can you make sure that your unit test code stays readable and maintainable over time? In the end, you simply have to apply modern unit testing patterns and best practices from the beginning (i.e. when creating your test case). While checklists such as this one here: The Ultimate Checklist for Better Unit Testing can help you assess to which extent your existing tests follow such guidelines, they still don’t help you a dime if you have no clue on how to apply these patterns in the first place. That is why in this article, I break down the most essential unit testing pattern for you, and demonstrate how you can apply it in practice.
Arrange – Act – Assert
This is the name of the pattern (or AAA in short). Its simplicity allows it to be applied to any kind of Unit Test, enabling Unit Tests to be more readable, structured, and maintainable. It allows you to structure your unit test based on the following three parts:
Arrange: This part encapsulates all the information required prior to executing the code unit under test. This includes (1) creating input data and variables to pass this input data to the code unit under test, (2) creating the expected result of passing the input data to the tested code unit (3) setting up any prerequisites in this code unit that needs to be tested, as well as (4) creating and preparing mocks of software logic that is required by the tested code unit.
Act: In this part, you pass the variables that contain the input data to the code unit under test, and record the result returned by the code unit. Make sure to also take care of any potential exceptions here!
Assert: Finally, you have a dedicated block for performing all the assertions between the expected result obtained in the arrange part of your unit test, and the actual result recorded in the act part. This might also include checking particular invocations on your mocked objects created in the arrange part.
By structuring your unit test based on these sections, clearly marking them using code comments, you
Examples using Java, JUnit, and Mockito
In the following, we demonstrate how you can use this AAA pattern in practice, by creating example test cases in Java using NUnit and Mockito. In this example, we want to test a method Person makeChild(Person father, Person mother) that returns a new child of type Person for the given parents, if both parents are fertile (this example is taken in a simplified version from the following post on clean unit testing: https://www.informatik-aktuell.de/entwicklung/methoden/clean-unit-testing-die-kunst-wartbare-unit-tests-zu-schreiben.html).
In a first case, we are verifying the age of the newly created child (see picture below for the test code). In the arrange part, we are setting up valid father and mother object, and the expected age of the returned child (=0). In the act part, we call the makeChild method of the Person class, with the created father and mother objects, and record the age of the returned child object. In the assert part, we simply assert that the recorded age is equal to the expected age. Pretty straight-forward, right?
In a second case, we want to verify that the makeChild method actually calls the isFertile method in both of the passed parent objects (see picture below for the test code). Therefore, in the arrange part, we have to set up the father and mother variables as mocks. In the arrange part, we simply verify that the isFertile methods was invoked in these mocks.
Another example test case here is to check that passing null as a father parameter lets the makeChild method throw an IllegalArgumentException – instead of e.g. a NullPointerException, or no exception at all (again, see picture below for the code here). Therefore, we simply add surround the call to the makeChild method with an assertThrows check from the JUnit library. In this case, the assert block is actually handled together with the Act part of the test case (as long as we don’t want to verify any further details of the error message).
You can download the code here:
I hope this helps you out !
Image by storyset on Freepik
When you visit any web site, it may store or retrieve information on your browser, mostly in the form of cookies. Control your personal Cookie Services here.
Daniel Lehner