Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Announcing aUnit, a new unit testing tool for aspects

How do you unit test aspects in isolation, in the same way that we might 
unit test a class?

Current unit-testing approaches for aspects are lacking in the following 
ways:

* you cannot easily unit test an individual aspect in isolation from the 
rest of the program
* you cannot easily test whether the pointcut expression associated with a 
piece of advice matches the join points you expect
* you cannot easily test whether the pointcut expression associated with a 
piece of advice matches unwanted join points
* you cannot easily test the body of advice in isolation from the rest of 
the program

For example, given the following simple aspect:

public aspect X {

  pointcut anInterestingCall() : call(* Account+.do*(..)) && 
within(org.xzy..*);

  before() : anInterestingCall() { ... }

}

We would like to write unit tests that verify:
* the pointcut matches a call to Account.doFoo() from within org.xyz.abc
* the pointcut matches a call to SubAccount.doGoo(int x) from within 
org.xyz.abc.def
* the pointcut does not match a call to Account.doFoo() from within 
org.qpr
* after matching at a join point, the post-conditions of the advice body 
are established
* and so on...

and we want to write these tests without necessarily having to create a 
package "org.qpr" and without having to weave and run external classes (to 
the one under test) in order to run the test cases.

Enter aUnit, a seamless extension to JUnit that makes it easy to write 
unit tests for aspects. aUnit works by letting the test programmer specify 
a sequence of join points (either programmatically, or parsed from a 
string format) that are then "played back" to the aspect. It is then easy 
to test after each join point or set of join points whether the aspect has 
responded as desired. Contextual information at the join points required 
by any advice (such as the objects bound to this or target, or the values 
of arguments) can be supplied by the test case programmer - as either 
"real" objects or as mock objects, in accordance with normal unit testing 
conventions. 

Here's an example of a simple aUnit test case:

public void testCallMatching() {
   String[] jps = new String[]({"call(void Account.doFoo()) 
within(org.xyz.abc)"});
   X x = X.aspectOf();
   playBack(jps,x);
   assertInvoked(x,"before","1");
    // ...
}

The exact style of the test cases has yet to be finalized, but this should 
give you the idea.

Where can I download a copy of aUnit?

Sadly, you can't. It doesn't exist yet. The idea came to me whilst I was 
out running in the woods this lunchtime. 

BUT, aUnit would make a great project for an MSc and/or for open-source 
development. Some of the implementation of aUnit would need to be tied to 
AspectJ implementation details, and we would work with the implementors to 
make sure that the necessary interfaces are in place and assistance is 
given. When finished, we would like aUnit to be contributed to the AspectJ 
tree under the CPL, to be included as part of the AspectJ distribution. 
The project contains some non-trivial challenges (like how to effectively 
test around advice containing calls to proceed) that should make it very 
interesting to work on, and could form a core part of every AspectJ 
developers toolkit.

It's something we'd love to work on but just don't have the time to 
dedicate to it (hands full with Java 1.5 support). 

So - do you want to build aUnit?  I'd be very interested to hear from 
developers or teams keen on taking on this challenge, or indeed from 
anyone on the list who has ideas about what aUnit should be like.

-- Adrian
Adrian_Colyer@xxxxxxxxxx


Back to the top