Test your Java application architecture with ArchUnit
For seasoned developers, one of the prominent principles in implementing software architectures is “less coupling” — reducing the dependencies between components. A number of software architectures are available to be followed but aren’t really monitored as they usually are enforced manually by lead developers or colleagues during code reviews.
I was thrilled when I came across ArchUnit, a Java test library that can be used to check dependencies between components as well as provide basic assertions to enforce your project’s architectural standards.
Testing your layer dependencies…
The layered architecture is one of the elementary web architecture where the application is partitioned it into three layers — controllers (or persistence), services (or domain), and persistence (or dao).
Each layer, ideally, should not be dependent on the ones above it: services may only be called by controllers, persistence may only be called by services (or even controllers depending on the team). With ArchUnit, it would be easy to detect classes violating the direction of dependency.
Suppose we have a simple package team
with two layers — controller and domain and we would want to enforce that the domain layers must not depend on any class on the controller layer.
Below is a sample ArchUnit test that enforces that classes in the `domain` layer must not access any class in the `controller` layer.
You can even go further with several layers like below. The persistence layer is responsible for saving objects to the database while the gateway layer is responsible for communicating with other services (such as in microservices).
Testing your component dependencies…
For bigger applications, the layered architecture doesn’t suffice and usually architectures tend to move to component-based where classes are grouped logically by their function or cohesiveness. By following the same pattern as our first example, we can implement this in ArchUnit!
Suppose we have two packages — jwt
and team
— and the jwt
package is dependent to the team
package. We would want to enforce that the tea
You can add an ArchUnit test to enforce that the team
package is accessible only by the jwt
package and the jwt
package shouldn’t be accessed by any other component (package).
On top of that, enforce naming conventions on components…
You can also enforce basic naming conventions in your application through ArchUnit.
Suppose we’re using the Spring framework in our application and we all want to impose the naming convention that all controller classes are suffixed with Controller
, and service classes with Service
.
The test below Furthermore, we would want them to be place
Summary
This is just a shallow view of what you can do with ArchUnit. They are your software architecture defenders and would be very effective if you add them to your CI pipeline.
Their use case documentation page contains more example on how you can exploit the library. Their documentation is superb and happy testing!