Mock Objects

Mock object testing is indispensible in situations where creating real objects would be redundant or require too much code to make testing feasible. The tapestry-test library provides a few conveniences to make managing mock objects a little easier in your own unit tests.

For example, if you were using EasyMock without extending TestBase you might have to write a test looking something like this:

import org.apache.tapestry.IMarkupWriter;
import org.testng.annotations.Test;
import static org.easymock.EasyMock.*;

@Test
public class MarkupWriterTest {

    public void test_Attribute_Write()
    {
        IMarkupWriter mw = createMock(IMarkupWriter.class);
        IRequestCycle cycle  = createMock(IRequestCycle.class);

        expect(cycle.isRewinding()).andReturn(false);
        mw.attribute("style", "display:block;background-color:red");

        replay(mw, cycle);

        MyWriterClass writer = new MyWriterClass();
        writer.renderAttributes(mw, cycle);

        verify(mw, cycle);
    }

    class MyWriterClass {

      public void renderAttributes(IMarkupWriter writer, IRequestCycle cycle)
      {
        if (cycle.isRewinding())
            return;

        writer.attribute("style", "display:block;background-color:red");
      }
    }
}

In particular you want to note that we had to pass in each mock we created in the replay(mw, cycle) method of EasyMock. This can get a little unweildy / painfaul at times so TestBase has made this part easier by keeping track of your mock objects for you.

The same class above re-written to use the TestBase features would look more like:

import org.apache.tapestry.IMarkupWriter;
import org.testng.annotations.Test;
import static org.easymock.EasyMock.*;

@Test
public class MarkupWriterTest extends TestBase {

    public void test_Attribute_Write()
    {
        IMarkupWriter mw = newMock(IMarkupWriter.class); // notice call changed to newMock() instead of createMock()
        IRequestCycle cycle  = newMock(IRequestCycle.class);

        expect(cycle.isRewinding()).andReturn(false);
        mw.attribute("style", "display:block;background-color:red");

        replay(); // notice no arguments

        MyWriterClass writer = new MyWriterClass();
        writer.renderAttributes(mw, cycle);

        verify();
    }

    class MyWriterClass {

      public void renderAttributes(IMarkupWriter writer, IRequestCycle cycle)
      {
        if (cycle.isRewinding())
            return;

        writer.attribute("style", "display:block;background-color:red");
      }
    }
}