[
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