JBoss.org Community Documentation

8.2.4. AOP with Mocks

- and intercepting a method invocation is just what aop does best. Our jboss-aop.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<aop>
   <bind pointcut="execution(public static bank.BankAccountDAO bank.BankAccountDAOFactory->getBankAccountDAO*())">
       <interceptor class="bank.BankAccountDAOInterceptor"/>
   </bind>
</aop>

The pointcut expression intercepts the factorycall bank.BankAccountDAOFactory.getBankAccountDAO*() and calls the interceptor bank.BankAccountDAOInterceptor.

package bank;

import org.jboss.aop.joinpoint.Invocation;
import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.aop.advice.Interceptor;

import util.MockService;

public class BankAccountDAOInterceptor implements Interceptor {

  public String getName() { return "BankAccountDAOInterceptor"; }

  public Object invoke(Invocation invocation) throws Throwable {
    try {
      MockService mockService = MockService.getInstance();

      Object mock = mockService.getMockForInterface( "BankAccountDAO");
      if(mock == null) {
        System.out.println("ERROR: BankAccountDAOInterceptor didnt find class!");
        // this will probably fail, but its the sainest thing to do
        return  invocation.invokeNext();
      }

      return mock;
    }
    finally {
    }
  }
}

Instead of returning invocation.invokeNext(), we ignore the invocation stack since we want to replace the invocation call with a mock implementation. The interceptor receives the invocation and get an instance of the singleton MockService. The use of MockService may not be clear, but we want the test to instanciate the mock objects. That way, the test can easily modify the input to the methods we want to test. The test creates an object of the mock and put it into the MockService with the interface name as the key. The Interceptor then tries to get the mock from MockService and return it.

package util;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MockService {

    private static MockService instance = new MockService();

    private Map mockReferences = null;

    protected MockService() {
        mockReferences = new Hashtable();
    }

    public static MockService getInstance() {
        return instance;
    }

    public void addMock(String c, Object mock) {
        mockReferences.put(c, mock);
    }

    public Object getMockForInterface(String myKey) {
      Set keys = mockReferences.keySet();

      for (Iterator iter = keys.iterator(); iter.hasNext();) {
        String key = (String) iter.next();
        if(myKey.equals(key)) {
          return mockReferences.get(key);
        }
      }
      return null;
    }

}