- We design and build extraordinary applications for companies looking to make the next great idea a reality.
- learn more
GWTTestCase and Server Side Mocking
While I like the fact that GWT supplies a mechanism for unit testing your applications, there is room for improvement on testing the interactions between the UI and server-side components. Based on everything I have read so far, testing GWT applications is an area which many people tend to gloss over or merely pay lip service to, leaving developers to fend for themselves on issues such as how to incorporate the use of mocks, or how to test GWT applications while keeping the test code clean and maintainable.
For the moment, let's consider a simple application where a client requests data from the server, and updates some content on the UI. We would like to assert that some content on the client can be updated with data returned by the server. For purposes of testing, the client code contains a package-level method which executes a remote call and updates the content area (asynchronously, of course). Here is a test case as we would like to write it:
public void testRemoteCallPopulatesContentArea() { // Mock out server call server.willReturn("Foo data"); // Client invocation client.executeCall(); // Assert client is updated assertContentArea("Foo data", client.getContentArea()); }
You can imagine additional testcases that assert behavior when the server throws an exception, returns an empty string, etc. Looks like a great test case so far (short & sweet), but as you have probably guessed, there are hoops to jump through in order to get this code to actually do what we intend it to do, each hoop deserving of a much longer, in-depth discussion of its own.
This test case should look pretty familiar to anyone who has used mocks before. In this test, we want to (1) mock out the behavior of the server component, (2) execute the call from the client's side, and (3) assert that the "content area" of the client contains the data we defined when we mocked out the behavior of the server component.
The work we will need to do breaks down as follows:
- Define a service that will support 'willReturn(String data)'
- Implement a mechanism for mocking out the actual implementation of the service method.
- Implement our assertion logic, taking into consideration the asynchronous nature of the client code, the use of GWT's Timer mechanism, etc.
The third item is the easiest to envision-- the method 'assertContentArea' wraps all of the Timer logic, defering execution of the actual 'assertEquals' invocation until the client has had a chance to execute the remote call and update the content area under test.
I have a few solutions in mind for the first two items, one of which involves using Spring to intercept calls to GWTShellServlet during execution of each test case. Can you guess how that one would work?
I'll delve into that side of things in following posts, but I hope this gets you thinking a bit more about readability of your test cases, and what test cases that extend GWTTestCase should really look like when they involve interactions with a back end component.
Topics: GWT, Test Driven Development, Testing
Comments: 1 so far
Leave a comment
About Pathfinder
Recent
- Thanksgiving 2008: What We’re Thankful For (In Rails)
- iPhone SDK: Testing with TextMate & GTM
- GWTQuery - JQuery-like Syntax in GWT
- Ask the readers: How do I fire native browser events in Prototype.js?
- News Rollup for the Week of November 17, 2008
- Rails ThreatDown!
- Automated Deployments Rock
- Bandwidth profiling Flex projects and more with Charles
- iPhone SDK: UIViewController Testing & TDD
- Icons are evil; so are menus - unless you do them right
Archives
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006


The actual solution to your problem is for rpc services to not be async within tests but rather to block. In this case you would use cast and use a proxy which implements the service interface and not the async interface(the one with AsyncCallback as the last parameter.)
Comment by mP, Sunday, November 11, 2007 @ 6:20 pm