Testing client-server communication with REST-Dispatch

A lot of the tests that are written in GWTP applications focus on client-server communication. Fetching and saving data is what most web applications do nowadays.

You can use whatever library to accomplish this work, however, in this post I use REST-Dispatch and Resource Delegates, from gwtp-extensions. They come with nice testing utilities that I’ll show you.

Prerequisites

In the previous post you learned how to hook into GWTP’s lifecycle to verify the behaviour of our application. Now we’ll do the same thing, but using the Delegates utilities to verify that a call to the server was made.

More specifically, we’ll verify that a call to a specific endpoint was executed with the correct parameters. We’ll also check to see that the application behaves correctly when a request succeeds or fails.

Since this article is based on an example we developed in a previous post, we strongly suggest that you read it. The new code will reside in the same repository, but in a different branch.

Cases

There are two behaviours we want to check:

  1. Fetching data from the server
  2. Saving data

Fetching data

Refer to this tutorial to learn how to set up REST-Dispatch up for your project. And then compare with our version on GitHub.

Now we will modify our example from our previous post. Instead of using a client service, we’ll use a fake backend. It can be written using anything: Java, C#, Dart, Go, or whatever you want.

At this point, when doing TDD, you either first want to know what endpoints you are going to call, or you can discover them (if you also own the backend). We’ll just assume you know the endpoints for the sake of the demo.

Here’s the interface we used to specify the endpoints:

So for the first case, we want to fetch data from the server in the method prepareFromRequest from the Presenter. Here’s the new test we wrote in UsersPresenterTest to illustrate that.

Let’s break it down. First you need to inject a ResourceDelegate<UserApi> into your test class. Then you want to set it up to use a specific resource, in our case UserApi. The way to do this would be to inject an instance of UserApi and add this line at the beginning of your test or in a test setup method:

givenDelegate(userApiResourceDelegate).useResource(userApi);

After that, you can simulate a call (and the response) to a specific endpoint pretty easily. In a test you can add the following piece of code:

List<User> users = new ArrayList<>();
givenDelegate(userApiResourceDelegate)
        .succeed().withResult(users)
        .when().getUsers();

This will tell the test framework to simulate a call to the getUsers() method of UserApi and return users as the result. You could also change things a little bit to make this a failing API call with the following code:

givenDelegate(userApiResourceDelegate)
        .fail()
        .when().getUsers();

There are many more options available to set up the way it fails. For more information, check out the source code.

Most of the time, when we develop web applications, we end up implementing our own RestCallbackImpl class that handles the failure cases on its own. Here’s our first implementation of RestCallbackImpl

Now we have to implement these changes in the Presenter.

After that, we have to do the same thing to adapt UserPresenterTest and UserPresenter. Here’s the new code:

Saving data

For the “Update user” part, we’re going to call the saveUser endpoint. Here are the tests:

After a bit of refactoring to make these new tests pass, here’s the Presenter code:

We also had to update the view code a little bit. You can see the final result on GitHub.

There are still the error cases to handle. For the sake of simplicity, we’ll just check when an error occurs when communicating with the server. That means we won’t check for specific exception or status codes, though we could if we wanted to.

Now we have to implement the mechanism to handle errors during client-server communication. This can be done by firing an event that is handled by an object that displays notifications or logs/prints the error in the console. In our case, we’ll just create a class that prints an error message in the JavaScript console.

If you want, you can test the RestCallbackImpl class by verifying that it raises an event when an error occurs. And you can also verify that the error handler is wired up and behaves correctly when called. We’ll leave that for you to do as an exercise.

Conclusion

After reading this post, you should be able to test the client-server interactions of your GWTP application. If you want to test this with a sample REST API, you can check out the one I’ve made in Dart.

In case you want to learn more, you can also have sub resources with REST-Dispatch. There’s a small section of the wiki that talks about this, and also shows how to test code using them.

Stay tuned for the next post (which should be the last one of this series), about all the “gotchas” with Jukito and GWTP, where you’ll see less trivial examples of JukitoModule configurations.

Happy coding!