Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Using aspectj to make Junit3 work as a functional test framework

On 3/22/07, Laurence Dawson <laurence.dawson@xxxxxxxxxxxxxx> wrote:
I am trying to use Junit 3 as a functional test framework, and aspectj
seems to offer a good way of solving the problem of passing context from
test to test - something junit is designed to avoid.
The aspects here allow me to use the same context in all the tests, and
by using a suite, I can easily set up the order of execution when that
is important. However it still seems a little off. There is an ugly cast
in the abstract aspect, and I don't yet see a way around it. I have
tried grabbing the context from the insert_context pointcut as a
ContextTarget<Context>, but that doesn't quite work - actually it gives
me a runtime exception in the ajc compiler version that I am using.
Does anyone see a way to simplify this - particularly a way to get rid
of the cast? There is also the issue of needing the test class to both
implement the ContextTarget interface, and use the annotation. That
might be easier to

The code looks like this:

//First I have an interface for the aspect to use:

public interface ContextTarget<Context> {
   public void setContext(Context ctx);
}

//The main aspect  is here
public abstract aspect ContextInjector<Context> {

   private Context ctx;
   public void setContext(Context context){
       ctx = context;
   }
     //override this to supply constructor execution join points
   abstract pointcut needs_context();

   pointcut insert_context(Object res):
       needs_context() &&
       this(res);

   after(Object res): insert_context(res){
       ((ContextTarget<Context>)res).setContext(ctx);
   }

}

//I use an annotation for the example concrete aspect:
//***********************************************************
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedsClientContext {
}
//***********************************************************

//Concrete descendents look like this - I need to create one per family
of tests:
//***********************************************************
public aspect ClientContext extends ContextInjector<ClientConnection> {
   {
       setContext(new ClientConnection("localhost", 2702));
   }

   pointcut needs_context():
       execution((@NeedsClientContext *).new(..)); //execution of
constructor
}
//***********************************************************

//So now I can define a Junit test case:
//***********************************************************
import junit.framework.TestCase;
public class ContextualTest<Context> extends TestCase
                                   implements ContextTarget<Context>{
   private Context context;
   public void setContext(Context ctx){
       context = ctx;
   }
   protected Context getContext(){
       return context;
   }
}
//***********************************************************

//And a 'real' test class in the family using ClientConnection looks
like this
//***********************************************************
import junit.framework.Assert;

@NeedsClientContext
public class Test1 extends ContextualTest<ClientConnection> {
 public void testOne(){
       System.out.println(getContext());
       Assert.assertTrue(true);
   }
}
//***********************************************************


This looks like an interesting AspectJ usage. However, if you need
functional testing I would recommend you TestNG: http://testng.org. It
has quite a few features that would help you out ;-).

./alex
--
.w( the_mindstorm )p.
_____________________________________
 Alexandru Popescu, OSS Evangelist
TestNG/Groovy/AspectJ/WebWork/more...
 Information Queue ~ www.InfoQ.com


Back to the top