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

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);
  }
}
//***********************************************************