Skip to content

AbstractComponentTest

PMJMendes edited this page Dec 18, 2014 · 6 revisions

AbstractComponentTest

AbstractComponentTest is the base class from which unit tests for wicket components should derive. The core of the class is based on WicketTester.startComponentInPage and the test life cycle is based on EasyMockSupport. EasyMock is used to create a mock AJAX request target, which is injected into WicketTester's running app for instantiated components to interact with.

How to use

The basic structure of a component test is as follows:

  1. Instantiate and initialize the component to test and any support objects
  2. Invoke startTest with the instantiated component to test
  3. Call getTarget to get a reference to the mocked AJAX request target
  4. Call any expected AJAX methods
  5. Call replayAll to set the mock to replay mode
  6. Call the methods to test on the component
  7. Call verifyAll to check the list of AJAX calls made by the component
  8. Call any additional asserts

Here's an example from the unit tests for com.premiumminds.webapp.wicket.drawer.DrawerManager:

private class TestDrawer extends AbstractDrawer {
	private boolean mbOnCloseCalled = false;
	public boolean getOnCloseCalled() {
		return mbOnCloseCalled;
	}
	@Override
	public void beforeClose(AjaxRequestTarget target) {
		super.beforeClose(target);
		mbOnCloseCalled = true;
	}
}

@Test
public void testCloseDrawerEvent() {
	Capture<EmptyPanel> p = new Capture<EmptyPanel>();
	DrawerManager m = new DrawerManager("test");
	TestDrawer d = new TestDrawer();
	m.push(d);
	startTest(m);

	getTarget().appendJavaScript("$('#"+d.getParent().getMarkupId()+"').unbind('hide-modal');");
	getTarget().appendJavaScript("$('#"+d.getParent().getMarkupId()+"').data('modal-drawer').isShown=true;");
	getTarget().appendJavaScript("$('#"+d.getParent().getMarkupId()+"').modaldrawer('hide');");
	getTarget().appendJavaScript("$('#"+d.getParent().getMarkupId()+"').removeClass('shown-modal');");
	getTarget().add(capture(p));
	replayAll();

	getTester().executeAjaxEvent(d.getParent(), "hide-modal");
	verifyAll();

	assertNull(m.getLast(AbstractDrawer.class));
	assertNull(m.getLastItemRelativePath());
	assertEquals(m, p.getValue().getParent());
	assertTrue(d.getOnCloseCalled());
}

Creating the mock AJAX request target is optional, as it may be necessary to invoke the component through a real target object. The two-argument form of startTest takes a boolean argument which controls the creation of the mock target, as shown in the following example, from the unit tests for com.premiumminds.webapp.wicket.AjaxComponentFeedbackPanel:

@Test
public void testMessagesCaught() {
	TestPanel p = new TestPanel("panel");
	p.setFeedbackFor(p.label);
	startTest(p, false);

	getTester().clickLink(p.link);

	assertEquals(p.label, p.getMessage().getReporter());
	assertEquals(msg, p.getMessage().getMessage());
	assertTrue(p.getMessage().isRendered());
	getTester().assertLabel(p.label.getPageRelativePath(), "Message!");
}

##Notes:

  1. Attempting to call getTarget before calling startTest results in a TestNotStartedException.
  2. The object returned by getTarget is guaranteed not to be null. However, if the two-argument form of startTest is called, with a false second argument, the object returned will not be used by the component and is essentially inert.
Clone this wiki locally