Skip to content

Unit testing basics

mojohn edited this page Sep 14, 2012 · 13 revisions

To be able to run client code in a JVM without any servlet container or browser plugin, gwt-test-utils requires a META-INF/gwt-test-utils.properties configuration file at the root of your project test classpath.

Assuming your application consists of two GWT modules and you want to test both, you'll have to declare them in this gwt-test-utils.properties:

com.example.mywebapp.YourModule1 = gwt-module
com.example.mywebapp.YourModule2 = gwt-module

Each declared module will be parsed by gwt-test-utils to build the set of classes which will be compiled in JavaScript and operated some magic modifications on them.

Note that you won't have to declare modules which are inherited by the module you've declared in gwt-test-utils.properties file. So, if YourModule2 was inheriting YourModule1, there is no need to declare YourModule1 in your configuration file.

First view unit test

In this example, we have a GWT module named com.googlecode.gwt.test.sample.Sample with a very simple SampleView written with UiBinder.

SampleView.ui.xml :

<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
  <g:HTMLPanel>
    <g:TextBox ui:field="textBox"></g:TextBox>
    <g:Button ui:field="button">Say Hello</g:Button>
    <g:Label ui:field="label" />
  </g:HTMLPanel>
</ui:UiBinder> 

SampleView.java:

public class SampleView extends Composite {

  interface SampleViewUiBinder extends UiBinder<Widget, SampleView> { }
  
  private static SampleViewUiBinder uiBinder = GWT.create(SampleViewUiBinder.class);
  
  @UiField
  Button button;
  
  @UiField
  Label label;
  
  @UiField
  TextBox textBox;
  
  public SampleView() {
    initWidget(uiBinder.createAndBindUi(this));
    label.setVisible(false);
    button.setEnabled(false);
  }
  
  @UiHandler("button")
  void onClick(ClickEvent e) {
    label.setText("Hello " + textBox.getText());
    label.setVisible(true);
  }
  
  @UiHandler("textBox")
  void onKeyPress(KeyUpEvent e) {
    button.setEnabled(textBox.getText().trim().length() > 0);
    label.setVisible(false);
  }
  
}

When user starts filling the textbox, the "Say Hello" button is enabled and when it is clicked, the label is displayed with text "Hello XXX". Couldn't be simpler !

The first unit test we need to write will simply assert that filling some text will enable the button, without displaying anything.
Then, we'll need a second unit test to ensure that when the textbox is filled with "Ben Linus", then a click to the button displays "Hello Ben Linus".

gwt-test-utils configuration:

Create the META-INF/gwt-test-utils.properties at the root of your test classpath:

com.googlecode.gwt.test.sample.Sample = gwt-module

Unit tests:

import static com.googlecode.gwt.test.assertions.GwtAssertions.assertThat;

@GwtModule("com.googlecode.gwt.test.sample.Sample")
public class SampleViewTest extends GwtTest {

  @Test
  public void fillTextShouldEnableButton() {
    // Arrange
    SampleView view = new SampleView();
    // ensure the widgets state at init
    assertThat(view.label).isNotVisible();
    assertThat(view.button).isVisible().isNotEnabled();
    
    // Act
    Browser.fillText(view.textBox, "John Locke");
    
    // Assert
    assertThat(view.button).isVisible().isEnabled();
    assertThat(view.label).isNotVisible();
  }
  
  @Test
  public void clickOnButtonShouldDisplayMessageInLabel() {
    // Arrange
    SampleView view = new SampleView();
    view.textBox.setText("Ben Linus");
    view.button.setEnabled(true);
    assertThat(view.label).isNotVisible();
    
    // Act
    Browser.click(view.button);
    
    // Assert: label should be visible and filled
    assertThat(view.label).isVisible().textEquals("Hello Ben Linus");
  }
}
  • The test class must extend GwtTest or one of its subclasses instead of the standard GWTTestCase. It provides the mechanism to allow the instantiation of GWT components without any web server.

  • The test class must be annotated with GwtModule to tell gwt-test-utils which module is under test in the current test class. Be careful to use a module you've declared in your META-INF/gwt-test-utils.properties with the gwt-module key/value pair. Otherwise, an exception would be thrown.

  • The Browser class provides some helpful methods to simulate user actions, such as click, blur, fillText, etc. More details here.

  • GwtAssertions.assertThat(...) static methods are an extension of fest-assert which provides fluent assertions for GWT widgets. More details here. You may want to import them statically.

Sources of this sample are available here.