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

  1. increase readibility by having a clear structure that the code for every test case follows, and thus
  2. increase maintainability because by knowing the responsibilities of each part of the test case (arrange, act, or assert), you also immediately see where you have to adapt something in your existing unit test, once your underlying requirements change.

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

Leave a Comment

We use cookies to give you the best online experience. By agreeing you accept the use of cookies in accordance with our cookie policy.

Privacy Settings saved!
Privacy Settings

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.

GetResponse, Google Analytics

We use LinkedIn Insight for marketing purposes. You can disable these cookies.

We use Google Analytics for marketing purposes. You can disable these cookies.
  • __utmz
  • __utma
  • _ga
  • _gat

We use GetResponse for marketing purposes. This service cannot be disabled, otherwise the website functions will be limited.

Decline all Services
Accept all Services
Get Free Access Now to
9 eBooks!
All about Automated Software Testing
Proven experts
Learn to save up to 75% of your test efforts
Get Free Access Now!
Get Access Now! & Save 50%
Personal Trainer FREE Nutrition Custom Workout App
Get Access Now!
eBook Download
Enter your details to get your free ebook!
All about Automated Software Testing
Download Free Ebook
Lorem ipsum dolor sit amet, consectetur adipiscing