When unit testing, mocking out your dependencies is standard practice. GWT is no exception. However, as you will discover, mocking your UI in GWT doesn’t work as you might expect.
Before we start with a sample, I just wanted to mention some best practices around GWT. It’s generally considered a best practice to use the Model-View-Presenter pattern (Part I, Part II, GWT 2.1 method). When you use this pattern, you avoid writing tests for your Views because they don’t contain any logic.
However, if you’re not following this pattern for whatever reason (existing code base, legacy, etc), you’ll want to unit test your UI logic. Furthermore, if you read the GWT 2.1 way of implementing MVP using Activities, you’ll find that some logic, like event handling, may creep into your Views for convenience sake. Therefore, I hope you find this useful in general.
Let’s build a simple example view.
With the class in place, we’d like to unit test the
validUsernameAndPassword method. Using my favourite unit testing framework TestNG and mocking framework Mockito, we’d come up with something like the following.
Seems simple enough. But if you try to run this test, you’ll be greeted with the following error.
java.lang.ExceptionInInitializerError at sun.reflect.GeneratedSerializationConstructorAccessor1.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) ... Caused by: java.lang.UnsupportedOperationException: ERROR: GWT.create() is only usable in client code! It cannot be called, for example, from server code. If you are running a unit test, check that your test case extends GWTTestCase and that GWT.create() is not called from within an initializer or constructor. at com.google.gwt.core.client.GWT.create(GWT.java:92) at com.google.gwt.user.client.ui.UIObject.(UIObject.java:179) ... 42 more
What this is telling you is that you have to run these tests in a
GWTTestCase, not a standard TestNG test. If you’ve had experience with
GWTTestCase, you know it’s very slow to initialize and not something you want to use for unit tests. To get around this, we have to use a secret class that’s not even documented in the Java doc,
GWTMockUtilities. The test class now looks like this.
Viola! Your tests pass as you expect them to. Hope that helps anyone doing UI unit testing in GWT.