Recently I wanted to add an aspect to some domain object, so that it was saved, the moment it changed state. However, after adding this aspect, the whole build of course failed, because a lot of the unit tests weren’t expecting the calls which were now woven into the domain object.

Of course I could alter all the unit tests so that they reflected the change in code. But this seems to defy the whole purpose of the aspect. Another option is of course postponing the weaving until after the unit tests. This didn’t seem to be the correct solution either, because I did want to write at least some tests to test that the aspect was doing its job.

So how did I get around this? The answer lay in Spring AOP. It shares much of the syntax of AspectJ, though it doesn’t (yet) offer all of the functionality. I’ve created a small sample for your reading pleasure.

At first we’ll look at a simple domain without aspects.

Victim.java

And Thief.java

Of course we have a unit test to test that the Thief indeed steals from a Victim:

Running this test shows that the Thief succeeds in stealing an item from the Victim. But of course, we can’t let Thiefs randomly steal from Victims. We need to introduce a PoliceAgent who can put the Thief in Jail. Let’s add an interface to Jail, and write a new test asserting that the Thief is put in Jail for stealing.

Jail.java

And the second unit test class:

Of course, this test fails, because there is no way to put the Thief in Jail yet. Let’s add the PoliceAgent as an aspect, because we want to intercept the Thief that is stealing:

PoliceAgentAspect.java

In order for Spring AOP to notice the aspect, and do the wiring, we need to add an applicationContext.xml with the correct beans. In this simple example, the following suffices (I’ve stripped the namespace declarations for readability):

You can see that in the Spring context I’ve mocked the Jail. This code previously was in the unit test. Also I’ve added the Thief as a bean which can be injected. This ensures that Spring can intercept the Thief with the PoliceAgentAspect. The modified test looks like this:

When we now run this test it succeeds. Also our old test still runs perfectly and provides a green light. Using Spring AOP, we can ensure that our code works when not using aspects, and that the adding of aspects to our code gives the intended results.