Search code examples
unit-testinggwtservletsgwttestcase

GWT rpc callback does not call after calling in GWTTestCase


I have written a GWTTestCase like this:

public void testClickButton() {
    SampleView view = new SampleView();
    RootPanel.get().add(view);
    view.textBox.setText("Saeed Zarinfam");

    assertEquals("", view.label.getText());

//        ButtonElement.as(view.button.getElement()).click();
    view.button.getElement().<ButtonElement>cast().click();

    assertEquals("Bean \"OCTO\" has been created", view.label.getText());
}

When i run this test it connect to my servlet (i added some log on my servlet) but the RPC callback does not call in my SampleView, junit say:

expected: <Bean "OCTO" has been created>, actual: <>

This is my callback in button click handler:

@UiHandler("button")
void onClick(ClickEvent e) {

    labelTest.setText("click button");

    AsyncCallback<FooBean> callback = new AsyncCallback<FooBean>() {
        public void onFailure(Throwable caught) {
            // Show the RPC error message to the user
            labelTest.setText("call fail");
            label.setText("Failure : " + caught.getMessage());
        }

        public void onSuccess(FooBean result) {
            labelTest.setText("call success");
            label.setText("Bean \"" + result.getName() + "\" has been created");
        }
    };

    // Make the call. Control flow will continue immediately and later
    // 'callback' will be invoked when the RPC completes.
    service.createBean("OCTO", callback);


}

Why GWT rpc callback does not call in this case?


Solution

  • RPC calls are asynchronous even in GWTTestCase. You have to call delayTestFinish() to tell the runner that the test is asynchronous, and call finish() "at some point in the future" to tell it it's finished and OK (otherwise you'll have a timeout).

    In your case, because the calling code has no way to know when the RPC call is finished, you can only do a wild guess at how many time it'll take, and use Timer.
    Better refactor your code to make it more testable if you ask me (note: a Selenium would work roughly the same: check a condition every second until a timeout, http://seleniumhq.org/docs/02_selenium_ide.jsp#the-waitfor-commands-in-ajax-applications, just like a Timer that you'd re-schedule up to N times if the condition is not met)

    See https://developers.google.com/web-toolkit/doc/latest/DevGuideTesting#DevGuideAsynchronousTesting