gwtXPDownloadsBlog

Testing GWT RPC services

Posted in GWT on January 10th, 2010 59 Comments

You may know that testing with GWTTestCase are very slow. And there are many posts about testing GWT applications without using GWTTestCase.

However, it is still hard to test our RPC remote services. That is the reason I decided to develop SyncProxy which can run directly from pure Java (non JSNI) code.

Simple Test case

For example, we have an helloApp application and we want to test our GreetingService

@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
  String greetServer(String name);
}

Assume the server side of application is running (whether in DevMode or deployed to an web server) and the servlet URL is configured at http://localhost/helloApp/greet

The test case

public class GreetingServiceTest extends TestCase{
  private static GreetingService rpcService =
    SyncProxy.newProxyInstance(GreetingService.class,
          "http://localhost/helloApp", "greet");

  public void testGreeting() {
    String result = rpcService.greetServer("SyncProxy");
    assertTrue((result != null) && (result.startsWith("Hello, SyncProxy")))
  }
}

Explanation

SyncProxy.newProxyInstance() method requires a service interface class, a base URL and a relative servlet path.

SyncProxy will search for RPC policy files (*.gwt.rpc files) to determine appropriate policy name for the service interface. Thus, we copy gwt.rpc files from war/helloApp directory to our test case classpath.

SyncProxy.newProxyInstance() will return a new proxy instance which implements our GreetingService interface.

Simulating Async

By design SyncProxy is synchronous, e.g it invoke the remote service and wait for the result. However, our GWT logic code invokes the remote service asynchronously. SyncProxy can simulate the ‘Async’ mode too.

GreetingServiceAsync rpcServiceAsync =
SyncProxy.newProxyInstance(GreetingServiceAsync.class,
          "http://localhost/helloApp", "greet");

The code is almost the same as section above, except we use the Async version of the remote service interface.

rpcService.greetServer("SyncProxy", new AsyncCallback<String>(){
  public void onFailure(Throwable caught) {
    ...
  }
  public void onSuccess(String result) {
    ...
  }
});

Download SyncProxy

Get SyncProxy (with source code) at our Downloads page

SyncProxy includes test suite (see the Java source file com.gdevelop.gwt.syncrpc.test.RPCSyncSuite) to test against the standard GTW RPC test.

Updated on 2010/03/03: Version 0.1.1 is released with cookie supports

Updated on 2010/03/13: New post Invoke GWT RPC services deployed on Google App Engine.

Share and Enjoy:

  • Google Bookmarks
  • Twitter
  • Facebook
  • Digg
  • Technorati
  • Live
  • DZone
  • Reddit
  • del.icio.us
  • Mixx
  • Netvibes
  • StumbleUpon
  • Yahoo! Bookmarks
  • Yahoo! Buzz
  • email
Leave a Comment »

59 Responses to “Testing GWT RPC services”

  1. Piotr Szaranski says:

    Thx for reply, i have another question now :)

    In our webApp we have resources with constrained access – standard form based authentication, which means we have to first login using POST and then we can use GWT services.

    This means in our integration tests we need to first login with POST (using httpclient for example), grab the cookies returned after authentication and push them inside CookieManager in RemoteServiceSyncProxy.

    Is there any possibility to achieve this without using reflection? Probably not, but its always better to ask first… :)

  2. Piotr Szaranski says:

    Method getDomainFromHost in class CookieManager makes some ugly work with doted hosts, for example:
    192.168.0.1 -> 168.0.1

    I think it is not a desired behavior :)

  3. ricardo says:

    Trung, thanks a lot for this great tool.

    I’ll share my experience. I use objectify and my types were not being sent from the server, I was getting “type was not assignable” serialization exceptions. I had to:
    -Initizalize my service in a slightly different way, as: myService = (MyService) SyncProxy.newProxyInstance(MyService.class,
    “http://127.0.0.1:8888/my_app/”, “my_serv”);
    -Copy my .gwt.rpc file to “null.gwt.rpc”, since the strongname that the server receives when the call comes from the test class is “null”

    And it works…

  4. m.w.e. says:

    I use sync proxy with junit. Make sure to set fork=yes in the junit task. Syncproxy was not picking up the correct classpath without it.

  5. yusuf says:

    Hi,

    i get this error
    java.lang.NoClassDefFoundError: com/google/gdata/client/GoogleAuthTokenFactory
    at de.megapharm.mm.web.testdata.RPCServiceTest.(RPCServiceTest.java:30)

    Have you a idea ?
    Thank You

  6. Trung says:

    SyncProxy depends in gdata java client, thus download it from code.google.com

    Hope this help

  7. Amos says:

    First, thanks for some great software. This is great to have.

    Here are collection of notes I had to go through to get this to work (including notes from people here):

    1. Get the Google Code libraries
    ———————————–
    http://code.google.com/p/gdata-java-client/downloads/list
    You want the Google Data java client.
    Add the jar file: jdata-core-1.0.jar to your classpath (or latest version)

    2. Change the Example (as Ricardo mentions above)
    ———————————————–
    A “/” is missing between the base URL and the service name.
    (MyService.class, “http://127.0.0.1:8888/my_app/”, “my_serv”); (note the “/” after my_app)

    3. Serialization Policy
    ————————————
    - Some classes will not serialize without the IsSerializable interface (although GWT doesn’t require it). Just add them.
    - In order to serialize a class to/from a service, it must appear in at least one method of the service both as input and output.
    - Example: MyClass dummyMethod(MyClass input);
    - Without the above, either serialization or deserialization will fail.
    - For example: void myMethod(MyInputClass input)
    – In this case, serialization will fail because the serialization policy only expects to deserialize the class and the serialization on the client side will fail.
    - If you see serialization policy exceptions you may want to follow this step.

    4. Add the GWT application directory to classpath
    —————————————–
    The GWT compiled files directory is required for proper serialization. The directory contains multiple files like this: 694BD6C5E9CCB9810670C827B93E270A.gwt.rpc and other files of type *.gwt.rpc, *.cache.png, *.cache.html

    The files of type *.gwt.rpc are the serialization policy for your classes and without this directory on the classpath the serialization will fail.

    Also, note that the files are only updated after you compile the GWT client files. The eclipse (IDE) compilation does not update these files.

  8. Ora Finona says:

    This is a bit off discussion, which I apologize for, but would you and your readers mind giving your thoughts about the recent oil spill, you’re opinion seriously helps and I can’t thank you enough for taking a few moments to give it. I left the URL in the appropriate field, thanks!

  9. Colin says:

    @Piotr Szaranski:

    I had the same issue with authentication, and I also was looking for more robust session management. I logged:

    http://code.google.com/p/gwt-syncproxy/issues/detail?id=6

    with an attached patch that while perhaps still a little rough around the edges provides support for plugging in login code.

Leave a Reply



Recent Comments:

  • Colin: @Piotr Szaranski: I had the same issue with authentication, and I also was looking for...
  • Ora Finona: This is a bit off discussion, which I apologize for, but would you and your readers...
  • Amos: First, thanks for some great software. This is great to have. Here are collection of notes...
  • Peter Frankmann: Hallo zusammen, Sehr gute Beiträge. Danke dafür. Werde wohl noch öfters mal...
  • Trung: SyncProxy depends in gdata java client, thus download it from code.google.com Hope this...