<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Till Death Do Us Part : Tag java, everything about java</title>
    <link>/tag/java.rss</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Thoughts around my marriage to technology</description>
    <item>
      <title>Easy(ier) Mock</title>
      <description>We use &lt;a href="http://www.easymock.org/"&gt;EasyMock&lt;/a&gt; as our mocking framework and it's pretty easy. You create a mock, set some expecations, put the mock into replay state, and exercise the class under test. Once you've exercised the code, you can verify all of the expectations you set. (For a complete description, see the EasyMock &lt;a href="http://www.easymock.org/EasyMock2_3_Documentation.html"&gt;documentation&lt;/a&gt;)

A typical test may look like this:

&lt;pre&gt;
public class StoreTest extends TestCase {
  @Test
  public void testThatCheckoutSendsPaymentInfoToProcessor() {
    CreditCardProcessor processor = EasyMock.createMock( CreditCardProcessor.class );
  
    PaymentInfo pi = new CreditCardPayment( "1234567890123456", "01/2008", 25.50 );

    EasyMock.expect( processor.handlePayment( pi )  ).andReturn( "confirmation-code" );

    EasyMock.replay( processor );

    Store store = new Store();
    store.setCreditCardProcessor( processor );
    store.checkout( pi );

    EasyMock.verify( processor );
  }
}
&lt;/pre&gt;

Pretty straightforward, but it&amp;apos;s a bit wordy. The first thing we did is use a static import to take care of the requirement to fully qualify the easymock methods. Our test now looks like this:
&lt;pre&gt;
public class StoreTest extends TestCase {
  @Test
  public void testThatCheckoutSendsPaymentInfoToProcessor() {
    CreditCardProcessor processor = createMock( CreditCardProcessor.class );
  
    PaymentInfo pi = new CreditCardPayment( "1234567890123456", "01/2008", 25.50 );

    expect( processor.handlePayment( pi )  ).andReturn( "confirmation-code" );

    replay( processor );

    Store store = new Store();
    store.setCreditCardProcessor( processor );
    store.checkout( pi );

    verify( processor );
  }
}
&lt;/pre&gt;

That&amp;apos;s a bit better (less typing), but the next issue came into the picture when we added additional mocks.

&lt;pre&gt;
public class StoreTest extends TestCase {
  @Test
  public void testThatCheckoutSendsPaymentInfoToProcessor() {
    double orderTotal = 25.50
    double receivablesBalance = orderTotal;
    CreditCardProcessor processor = createMock( CreditCardProcessor.class );
    AccountsReceivable receivables = createMock( AccountsReceivable.class );
  
    Order o = new Order( "123456",orderTotal );
    PaymentInfo pi = new CreditCardPayment( "1234567890123456", "01/2008", o );

    expect( processor.handlePayment( pi )  ).andReturn( "confirmation-code" );
    expect( receivables.add( o )  ).andReturn( receivablesBalance );

    replay( processor, receivables );

    Store store = new Store();
    store.setCreditCardProcessor( processor );
    store.setAccountsReceivable( receivables );
    store.checkout( pi );

    verify( processor, receivables );
  }
}
&lt;/pre&gt;

The problem with the above code is that it's easy to forget to replay and verify the new mock, it&amp;apos;s three steps instead of one. To resolve this, we turned to Java 5 generics and a new base class:

&lt;pre&gt;
public class TestCaseWithMocks {
	private List&amp;lt;Object&amp;gt; mocksUsed;
	
	@Before
	protected void createMockList() {
		mocksUsed = new ArrayList&amp;lt;Object&amp;gt;();
	}
	
	protected &amp;lt;T&amp;gt; T mock(Class&amp;lt;T&amp;gt; target) {
		T mock = EasyMock.createMock(target);
		mocksUsed.add( mock );
		return mock;
	}
	
	protected void replay() {
		EasyMock.replay( mocksUsed.toArray() );
	}
	
	protected void verify() {
		EasyMock.verify( mocksUsed.toArray() );
	}
}
&lt;/pre&gt;

Our base class now creates the mocks for us and keeps track of the mocks created by our test. Then, when verifying/replaying the mocks, it will verify/replay them all.

Our test case now looks like the following:

&lt;pre&gt;
public class StoreTest extends TestCase {
  @Test
  public void testThatCheckoutSendsPaymentInfoToProcessor() {
    double orderTotal = 25.50
    double receivablesBalance = orderTotal;
    CreditCardProcessor processor = mock( CreditCardProcessor.class );
    AccountsReceivable receivables = mock( AccountsReceivable.class );
  
    Order o = new Order( "123456",orderTotal );
    PaymentInfo pi = new CreditCardPayment( "1234567890123456", "01/2008", o );

    expect( processor.handlePayment( pi )  ).andReturn( "confirmation-code" );
    expect( receivables.add( o )  ).andReturn( receivablesBalance );

    replay();

    Store store = new Store();
    store.setCreditCardProcessor( processor );
    store.setAccountsReceivable( receivables );
    store.checkout( pi );

    verify();
  }
}
&lt;/pre&gt;

Now, when we add a new mock, we add it in one place, the replay and verify take care of themselves.

</description>
      <pubDate>Fri, 02 Nov 2007 15:46:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:bc576426-067f-434a-b4bf-8076a25ac6c8</guid>
      <comments>http://blog.bcarlso.net/2007/11/02/easy-ier-mock#comments</comments>
      <category>java</category>
      <category>tdd</category>
      <link>http://blog.bcarlso.net/2007/11/02/easy-ier-mock</link>
    </item>
  </channel>
</rss>
