Friday, May 30, 2008

GWT Dictionary and Unit Tests

Much like Firing onClickListeners in GWT Unit Tests, unit testing a GWT Dictionary is possible, but it is neither:
  • intuitive

  • documented anywhere at all (that I could find)

The problem is...

Dictionary.getDictionary( "bundle" );

...requires a JavaScript-level variable bundle to be declared on your 'host HTML page'. When the GWT application is running normally, the 'host HTML page' is the index.html page. However, when running unit tests, there is no host HTML page, so where to define that JavaScript-level variable?

The answer is in those tricky JSNI methods again. Just do...

public class MyTest extends GWTTestCase {

      public void testSomething() {
         prepareBundle();
         ...your tests here...
      }

      ...your other tests here...

      native void prepareBundle() {
      /*-{
         $wnd["bundle"] = {
            "dateOfBirth": "Date of Birth",
            "surname": "Surname"
         };
      }-*/;

...and use the special $wnd variable to initialize a JavaScript variable bundle prior to running your tests.

Hope that helps somebody. This is going to be in the upcoming release of Metawidget.

Friday, May 16, 2008

Firing onClickListeners in GWT Unit Tests

Firing event handlers, such as onClickListener, from GWT Unit Tests is possible, but it is neither:
  • intuitive
  • well documented
You can't just do...

myButton.click();

...because that clicks the button without firing any listeners. Instead, within your GWTTestCase-derived unit test, put a method like this:

private native void fireClickListeners( FocusWidget w )
/*-{
  w.@com.google.gwt.user.client.ui.FocusWidget::fireClickListeners()();
}-*/;

It looks funny I know. Make sure you:
  • include the native keyword, which the GWT compiler understands to mean JavaScript Native Interface (JSNI), rather than Java Native Interface (JNI)

  • include the starting and ending comment delimiters, because the code inside the function is actually JavaScript code, which
    means nothing to the Java compiler

You can then call this method just as you would a normal method:

fireClickListeners( myButton );

Hope that helps somebody. I'm using this in the upcoming release of Metawidget.