Testing patterns in GWTP

This post is intended to be the next steps towards a TDD approach with GWTP. We’ll try to show you the patterns and workflow of writing a GWTP application in a TDD fashion.

Prerequisites

Testing patterns in GWTP

In GWTP, most tests are focused on the Presenter. This is mainly due to the fact that the Presenter can be seen as a bridge between the display and the business logic.

Nearly all tests for a Presenter are about verifying interactions between different components, whether it is a service class, an event bus, the PlaceManager or a ResourceDelegate.

In this posts we will go through these specific topics:

  • Interactions Presenter → View
  • Interactions View → Presenter
  • Interactions with the PlaceManager
  • Interactions with the EventBus

Interactions Presenter → View

The first case is to populate the view with data taken from a client side service or a backend. Let’s say we want to fill a label with the name of a user.

When data doesn’t need to change once a Presenter is bound, it is a good idea to put the expensive work in the onBind() method. Here’s how we would write the test and then the Presenter code.

You may have noticed that we don’t include a test for the view here. The reason is fairly simple: we do not write it at all. This is justified by the fact that views usually don’t have much logic; they’re pretty “dumb”. Pass a value or an object to the view and then assign it to a field.

Besides, to be able to write a test case for a view class, one would need to use GWTTestCase or something similar to be able to inspect the content of the DOM. We personally don’t recommend doing this. View tests often happen to be brittle and thus hard to maintain, and don’t bring much value to the developer.

Interactions View → Presenter

The second case comes from user interactions with the View (ie: click events, text change events, etc.) It first starts with a handler triggered in the View (which you don’t test because of the reasons mentioned earlier) that will call a method on its UiHandlers (most likely, a Presenter).

To continue our example, let’s have a text box and a button in the view that will let the user update the username label. This is one of the most common cases when developing Web applications (fetching, saving, displaying data). The flow should go like this:

  1. The user clicks on the Save button
  2. The View grabs the new name from the text box’s value
  3. The View calls its UI handler with the new value
  4. The Presenter delegates the save request to the service.
  5. The Presenter tells the view to display the new name
  6. The View displays the new name in the label

Here’s how it looks like:

Interactions with the PlaceManager

The interactions with the PlaceManager are caused by two scenarios:

  1. Displaying different information based on the place (nametoken and parameters)
  2. Changing the current place

For the first one, this decision is made in the prepareFromRequest method of a Presenter. This method receives the new PlaceRequest object containing the nametoken and the parameters.

Let’s adapt our current example so that, now, we have multiple users in the system, and based on the ID parameter that is passed in the PlaceRequest, we have to display that specific user’s information.

Our first test will need to check that the view displays the correct user’s information, based on an ID received as a parameter. Here’s how it looks like:

And now we have to implement this in our Presenter:

The other type of interaction is when you want to reveal a particular place. Currently, you have to know the exact URL to be able to edit a user’s information. There’s no homepage, so let’s add another page containing the list of users with the proper link to edit the users’ name. This will also be the place to return to once we save a user, using the PlaceManager. You can get an overview of the complete code here.

Interactions with the EventBus

When interacting with the EventBus, there are two kinds of actions you want to verify : firing and handling an event.

We added a delete button to remove the users from the page. We’ll see how the UserService fires an event when a user gets deleted, and how the UsersPresenter handles that situation.

Here’s the code of the event we want to raise, and its handler:

Now we want to adapt the UserService to fire that event when needed. Let’s write the test for that:

And now implement it:

That’s it!

Now in the Presenter, we have to handle that. Let’s write the tests to wire the UiHandlers and the Presenter.

As you can see here, there’s a little trick with Jukito that we have to add (the JukitoModule part), so that the onBind()method doesn’t get called automatically when running the test. We’ll talk a little bit more about this at the end of the post.

And then the event handling:

Finally, the implementation:

Voilà!

As a bonus, here’s the final code with a working view.

Conclusion

With this post, you should now be able to understand how to write basic tests in a TDD workflow in GWTP. There are a couple more complex scenarios that we’ll talk about in the next posts. Namely, testing communication with a server using REST-Dispatch and also tricks, tips and gotchas with Jukito, like the JukitoModule configuration that you saw in the examples above.

Note that we would have designed the application a bit differently if it were for a real project, but this was mostly for the sake of the demonstration.

Have fun!