Hi,

I'm using GwtMockito for GWT testing, and in general it works great. But, 
after updating GWT from 2.5.1 to 2.6.0-rc3 one of our tests started failing:

~~~~
java.lang.RuntimeException: Cannot call native method
    at 
com.google.gwt.core.client.impl.UnloadSupport.setTimeout0(UnloadSupport.java)
    at 
com.google.gwt.core.client.impl.UnloadSupport.setTimeout(UnloadSupport.java:86)
    at com.google.gwt.core.client.impl.Impl.setTimeout(Impl.java:278)
    at com.google.gwt.user.client.Timer.schedule(Timer.java:103)
    at 
com.collaborne.frontend.client.composite.notification.NotificationComposite.onUserNotificationEvent(NotificationComposite.java:130)
    at 
com.collaborne.frontend.client.composite.notification.NotificationCompositeTest.onUserNotificationEventSetsMessageTextInnerText(NotificationCompositeTest.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at 
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at 
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at 
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at 
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at 
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at 
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at 
com.google.gwtmockito.GwtMockitoTestRunner.run(GwtMockitoTestRunner.java:243)
    at 
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at 
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
~~~~

The test:
~~~~
@RunWith(GwtMockitoTestRunner.class)
public class NotificationCompositeTest {
    @Mock EventBus eventBus;
    
    @Test
    public void onUserNotificationEventSetsMessageTextInnerText() {
        UserNotificationEvent event = new 
UserNotificationEvent(Type.INFORMATION, "message");
        NotificationComposite composite = new 
NotificationComposite(eventBus);
        
        composite.onUserNotificationEvent(event);
        
        verify(composite.messageText).setInnerText(event.getMessage());
    }
}
~~~~

The method #onUserNotificationEvent() itself (trimmed a bit):
~~~~
    @EventHandler
    protected void onUserNotificationEvent(UserNotificationEvent event) {
        // Disarm an existing timer early, to avoid flickering
        messagePanelTimer.cancel();
        
        messageText.setInnerText(event.getMessage());

        //
        // snip some more preparation
        //

        // Show the panel, and (re-)arm the auto-close timer
        setVisible(true);
        messagePanelTimer.schedule(15 * 1000);
    }
~~~~

The timer is created in the composite constructor:
~~~~
        messagePanelTimer = new Timer() {
            @Override
            public void run() {
                hide();
            }
        };
~~~~

I managed to work around this by creating a "DelegatingTimer", and using 
GWT.create() to construct it, which then GwtMockito simply mocks out:
~~~~
public class DelegatingTimer extends Timer {
    private Runnable delegate;

    /**
     * Set the delegate to use for the next {@link #run()} invocation.
     * 
     * @param delegate the delegate, or {@code null} to unset the delegate
     */
    public void setDelegate(Runnable delegate) {
        this.delegate = delegate;
    }
    
    @Override
    public void run() {
        if (delegate != null) {
            delegate.run();
        }
    }
}
~~~~~


Now, the questions:
1) Is this something GwtMockito needs to handle? If so, how? UnloadSupport 
is internal, and not created using GWT.create() in a unit test context. 
2) Is the approach using the DelegatingTimer "reasonable?" 

Any advise would be greatly appreciated :)

Best Regards,
--
Andreas

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to