Power of EasyMock 2 with Java 1.4

I have been long time wondering if it is possible to improve API of EasyMock Java 1.3 version so that you get rid of MockControls in your test code. So as an experiment I wrote following classes to check how much work does this require. I wanted to achieve same simple API as in EasyMock 2.x but still be Java 1.4 compatible. Also I didn't want to rewrite EasyMock or extend it in any fragile way.

Here are the resulting classes that currently support only returning booleans but with some simple coding it should be possible to make it support whole API of EasyMock:

public class EasyMockHelper {

  private static MockControl lastInvokedControl;

  public static ReturnValueSetter expect(boolean b) {
    return new ReturnValueSetter(lastInvokedControl);
  }

  public static Object getMock(Class cl) {
    Object proxy = Proxy.newProxyInstance(cl.getClassLoader(), new Class[]{cl},
            new MockInvocationHandler(MockControl.createControl(cl)));
    return proxy;
  }

  private static class MockInvocationHandler implements InvocationHandler {

    private final MockControl control;

    public MockInvocationHandler(MockControl control) {
      this.control = control;
    }

    public MockControl getControl() {
      return control;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
      Object retValue;
      try {
        retValue = method.invoke(control.getMock(), args);
      } finally {
        lastInvokedControl = control;       
      }
      return retValue;
    }
  }

  public static void replay(Object mock) {
    getControl(mock).replay();
  }

  private static MockControl getControl(Object mock) {
    MockInvocationHandler invocationHandler = (MockInvocationHandler) Proxy
            .getInvocationHandler(mock);
    return invocationHandler.getControl();
  }

  public static void verify(Object mock) {
    getControl(mock).verify();
  }
}
public class ReturnValueSetter {

  private final MockControl lastInvokedControl;

  public ReturnValueSetter(MockControl lastInvokedControl) {
    this.lastInvokedControl = lastInvokedControl;     
  }
 
  public void andReturn(boolean b) {
    lastInvokedControl.setReturnValue(b);
  }

}

And here is basic test:

public class EasyMockHelperTest extends TestCase {

  private interface Sample {
    boolean getBoolean();
  }

  public void testExpectReturnTrue() throws Exception {
    Sample mock = (Sample) EasyMockHelper.getMock(Sample.class);

    EasyMockHelper.expect(mock.getBoolean()).andReturn(true);
    EasyMockHelper.replay(mock);

    assertTrue(mock.getBoolean());
  }

  public void testExpectReturnFalse() throws Exception {
    Sample mock = (Sample) EasyMockHelper.getMock(Sample.class);

    EasyMockHelper.expect(mock.getBoolean()).andReturn(false);
    EasyMockHelper.replay(mock);

    assertFalse(mock.getBoolean());
  }

  public void testExpectMultipleCalls() throws Exception {
    Sample mock = (Sample) EasyMockHelper.getMock(Sample.class);

    EasyMockHelper.expect(mock.getBoolean()).andReturn(false);
    EasyMockHelper.expect(mock.getBoolean()).andReturn(true);
    EasyMockHelper.replay(mock);

    assertFalse(mock.getBoolean());
    assertTrue(mock.getBoolean());
  }
}

Even if above code contains some bugs and does not support all scenarios I think it proves that it should be quite easy to improve EasyMock Java 1.3 version.

Here is the source

Labels

easymock easymock Delete
testing testing Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Feb 18, 2008

    Risto Alas says:

    I like the idea. I don't have time to look into this now but I'll investigate it...

    I like the idea. I don't have time to look into this now but I'll investigate it later, to see if we can use something like this on our project.

  2. Feb 19, 2008

    Ürgo Ringo says:

    Aleksei will start implementing this extension. https://intranet.aqris.com/jira/...

    Aleksei will start implementing this extension. https://intranet.aqris.com/jira/browse/TDO-346

    We will keep you updated

    1. Feb 19, 2008

      Risto Alas says:

      Nice Coould I also request some convenience methods like replayAll()?

      Nice

      Coould I also request some convenience methods like replayAll()?

      1. Feb 19, 2008

        Ürgo Ringo says:

        Definitely. repleayAll, verifyAll should be available

        Definitely. repleayAll, verifyAll should be available