GWT 1.6 MVP and testing, part 1

posted on June 25, 2009 in coding

After successfully building the eventBus, I decided to extend the application to use the MVP (Model-View-Presenter) pattern. The use of this pattern is nicely explained on the google testing blog. Since it’s quite a new way of doing this, there is very little example code available.
Since the gwt best practices are mostly focused on testing, and testing is an invaluable part of application design, we’ll write the test first. I’m not going in detail about Test Driven Development, there are plenty of good books around.

I’ll start with the code straight from the I/O session slides, since that’s what we want.
1. The MockClickEvent, a fake ClickEvent we can send:

public class MockClickEvent extends ClickEvent { }

Easy. And the MockHasClickHandlers class, implementing the minimum required:

class MockHasClickHandlers implements HasClickHandlers {
	ClickHandler lastClickHandler;
	public HandlerRegistration addClickHandler(ClickHandler handler) {
		lastClickHandler = handler;
		return new HandlerRegistration() {
			public void removeHandler() { }
		};
	}
	public void fireEvent(GwtEvent<?> event) { }
}

Now we have a fake click event we can send, and a fake class that can be clicked on, aka a fake button. Great.
2. We’re also going to send a String to the table, to fill the added row with. This could be an example of sending values with events.
For this fake string to work, we also need a mock textfield (also only minimum required code):

public class MockHasValue implements HasValue<string> {
	String lastValue;
 
	public String getValue() {
		return lastValue;
	}
	public void setValue(String value) {
		this.lastValue = value;
	}
	public void setValue(String value, boolean fireEvents) {
		setValue(value);
	}
	public HandlerRegistration addValueChangeHandler(
			ValueChangeHandler<string> handler) {
		return null;
	}
	public void fireEvent(GwtEvent<?> event) {
	}
}

All this we combine in one mock AddRowWidget:

public class MockAddRowWidget implements AddRowWidgetInterface {
 
	// the Button
	MockHasClickHandlers save = new MockHasClickHandlers();
	// The Textfield
	MockHasValue value = new MockHasValue();
 
	public HasClickHandlers getSendButton() {
		return save;
	}
	public HasValue<string> getTextValue() {
		return value;
	}
}

So what do we have so far?
A mock Composite that contains:
– a mock button on which can be (mock) clicked.
– a mock textfield with a value string.

Next: we need a mock table, implementing the SpecialTable interface (a custom object that has a addRow function), that can listen to the mock event and react accordingly:

public class MockSpecialTableWidget implements SpecialTableInterface {
	public String rowValue;
 
	public void addSpecialRow(String value) {
		this.rowValue = value;
	}
}

Almost done! All the ingredients are in place, let’s create our test:

public void testAddRow()
	{
 
		// initialize our mock objects
		MockAddRowWidget mockWidget = new MockAddRowWidget();
		MockSpecialTableWidget mockTableWidget = new MockSpecialTableWidget();
 
		create an eventBus
		HandlerManager eventBus = new HandlerManager(null);
 
		// the Presenter class of the listening table binds the (mock) table widget to the eventBus
		// with a tableRowEventHandler
		SpecialTablePresenter specialTablePresenter = new SpecialTablePresenter(mockTableWidget, eventBus);
 
		// same for the AddRowPresenter: binding (clicking on) the widget to firing the TableRowEvent with the eventBus
		AddRowPresenter addRowPresenter = new AddRowPresenter(mockWidget, eventBus);
 
		// set TextField value
		mockWidget.value.setValue("testString");
		// fake a click on the mock button
		mockWidget.save.lastClickHandler.onClick(new MockClickEvent());
 
		// Did it pass through?
		assertTrue(mockWidget.value.getValue() == mockTableWidget.rowValue);
	}

And result: green bar!
unit test 1

This code is only completely relevant if combined with the MVP code.which will be shown in a next post. Stay tuned!

5 Comments »

  1. […] table) are now completely separated, the timing of the event is no longer imporant. Next Up: – Adding testing. – Adding MVP. – working with GIN. – […]

    Pingback by code » Building a GWT 1.6 application: Managing events with an eventBus — June 26, 2009 @ 3:46 pm

  2. […] http://www.webspin.be/2009/06/gwt-1-6-mvp-and-testing-part-1/ Possibly related posts: (automatically generated)How to setup Ext js-GWT : GXT and Example on Eclipse Ganymede 3.4 […]

    Pingback by GWT Atchitecture anyone? « TechnoBuzz — August 15, 2009 @ 11:26 pm

  3. Interesting !

    I suggest a possible refinement:

    change

    “public class MockAddRowWidget implements AddRowWidgetInterface”

    to

    “public class MockAddRowWidget extends Widget implements AddRowWidgetInterface”

    and then change

    “mockWidget.save.lastClickHandler.onClick(new MockClickEvent());”

    to

    “mockWidget.fireEvent(new MockClickEvent());”

    Comment by Francesco Pasqualini — September 2, 2009 @ 6:37 am

  4. I correct my previous post, here is the possible refinement (remove lastClickHandler and MockClickEvent):

    change

    <<
    class MockHasClickHandlers implements HasClickHandlers {
    public HandlerRegistration addClickHandler(ClickHandler handler) {
    lastClickHandler = handler;
    return new HandlerRegistration() {
    public void removeHandler() { }
    };
    }
    public void fireEvent(GwtEvent event) { }
    }
    >>

    to

    <>

    and change

    mockWidget.save.lastClickHandler.onClick(new ClickEvent());

    to

    mockWidget.save.fireEvent(new ClickEvent());


    every custom widget extends Widget and so inerits the magical fireEvent method

    Comment by Francesco Pasqualini — September 2, 2009 @ 7:15 am

  5. …I try again…

    I correct my previous post, here is the possible refinement (remove lastClickHandler and MockClickEvent):

    change


    class MockHasClickHandlers implements HasClickHandlers {
    public HandlerRegistration addClickHandler(ClickHandler handler) {
    lastClickHandler = handler;
    return new HandlerRegistration() {
    public void removeHandler() { }
    };
    }
    public void fireEvent(GwtEvent event) { }
    }

    to


    class MockHasClickHandlers extends Widget implements HasClickHandlers){

    public HandlerRegistration addClickHandler(ClickHandler handler) {
    return addHandler(handler, ClickEvent.TYPE);
    }
    }

    and change

    mockWidget.save.lastClickHandler.onClick(new ClickEvent());

    to

    mockWidget.save.fireEvent(new ClickEvent());


    every custom widget extends Widget and so inerits the magical fireEvent method

    Comment by Francesco Pasqualini — September 2, 2009 @ 7:18 am

RSS feed for comments on this post. TrackBack URI

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

-->

Blom Inrichtingen - interieurprojecten in de gezondheidszorg