Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A widget that has an existing parent widget may not be added to the detach list #58

Open
lynx-r opened this issue Nov 7, 2015 · 4 comments

Comments

@lynx-r
Copy link

lynx-r commented Nov 7, 2015

I try to test my view with GwtMockito and have this problem:

java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list
    at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:137)
    at com.google.gwt.user.client.ui.RootPanel.get(RootPanel.java:211)
    at com.google.gwt.user.client.ui.RootPanel.get(RootPanel.java:151)
    at com.ait.lienzo.client.core.shape.Node.<clinit>(Node.java:112)
    at sun.reflect.GeneratedSerializationConstructorAccessor17.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:40)
    at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:59)
    at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
    at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
    at org.mockito.Mockito.mock(Mockito.java:1243)
    at org.mockito.Mockito.mock(Mockito.java:1216)
    at com.google.gwtmockito.GwtMockito$Bridge.create(GwtMockito.java:317)
    at com.google.gwt.core.shared.GWT.createImpl(GWT.java:83)
    at com.google.gwt.core.client.GWT.create(GWT.java:86)
    at online.draughts.rus.client.application.home.PlayComponentView.initEmptyDeskPanel(PlayComponentView.java:195)

I try to create LienzoPanel in PlayComponentView like this:

Layer initDeskRect = GWT.create(Layer.class);
Rectangle contour = GWT.create(Rectangle.class);
...
lienzoPanel = GWT.create(LienzoPanel.class);
lienzoPanel.setBackgroundLayer(initDeskRect);
...

I investigated that there is problem in Node.java:

static
{
    RootPanel.get().getElement().getStyle().setProperty("webkitTapHighlightColor", "rgba(0,0,0,0)");
}

Is this problem on side of Lienzo?

@ekuefler
Copy link
Collaborator

Interesting. I tried making my own class containing the same static initializer block and GWT.creating that class in a test and it was able to call get on the RootPanel without any problems. Can you try creating a test that does nothing but call GWT.create(LienzoPanel.class) and seeing if that fails?

Is it possible some other part of your code is modifying the RootPanel in some way? From a quick glance at the RootPanel source, it seems like this would only happen if the RootPanel ended up getting inserted into the DOM hierarchy somehow, which I wouldn't expect to be caused by GwtMockito.

Whatever the root cause is, it's possible you might be able to work around the problem by annotation your test with @WithClassesToStub(RootPanel.class) or @WithClassesToStub(Node.class). That would prevent it from going down the code path that causes the exception, but might have other unanticipated side effects.

@lynx-r
Copy link
Author

lynx-r commented Nov 15, 2015

I tried to annotate class with @WithClassesToStub(Node.class) no changes but if I annotate it with @WithClassesToStub(RootPanel.class) I get this exception:

com.google.gwtmockito.GwtMockitoTestRunner$FailedCastException: The test failed with a ClassCastException. This often indicates that you are using a library that invokes JavaScriptObject.cast() to convert an object from one type to another in a way that can't be mimicked in pure Java. There are a few ways to deal with this:
  1) Inject the class that calls cast() into the class being tested so that you can replace it with a mock.
  2) Annotate your test class with @WithClassesToStub and pass in the class that is causing problems.
  3) If the class is part of GWT and not a third-party library, try reporting it on the issue tracker at https://github.com/google/gwtmockito/issues and it might be possible to  insert a workaround.

    at com.google.gwtmockito.GwtMockitoTestRunner$1.testFailure(GwtMockitoTestRunner.java:320)
    at org.junit.runner.notification.RunNotifier$4.notifyListener(RunNotifier.java:139)
    at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:61)
    at org.junit.runner.notification.RunNotifier.fireTestFailures(RunNotifier.java:134)
    at org.junit.runner.notification.RunNotifier.fireTestFailure(RunNotifier.java:128)
    at org.junit.internal.runners.model.EachTestNotifier.addFailure(EachTestNotifier.java:23)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:275)
    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:367)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassCastException: com.google.gwt.core.client.JavaScriptObject$$EnhancerByMockitoWithCGLIB$$9c9ac146 cannot be cast to com.ait.tooling.nativetools.client.NObjectBaseJSO
    at com.ait.tooling.nativetools.client.NObjectBaseJSO.createNObjectBaseJSO(NObjectBaseJSO.java:34)
    at com.ait.tooling.nativetools.client.NObjectJSO.make(NObjectJSO.java:25)
    at com.ait.lienzo.client.core.shape.Attributes.<init>(Attributes.java:83)
    at com.ait.lienzo.client.core.shape.Node.<init>(Node.java:144)
    at com.ait.lienzo.client.core.shape.ContainerNode.<init>(ContainerNode.java:55)
    at com.ait.lienzo.client.core.shape.Layer.<init>(Layer.java)
    at online.draughts.rus.client.application.home.PlayComponentView.initEmptyDeskPanel(PlayComponentView.java:199)
    at online.draughts.rus.client.application.home.PlayComponentView.<init>(PlayComponentView.java:120)
    at online.draughts.rus.client.application.home.HomeViewTest.testHomeView(HomeViewTest.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    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)
    ... 18 more

My test:

    PlayComponentView.Binder playBinder = GWT.create(PlayComponentView.Binder.class);
    DraughtsMessages messages = GWT.create(DraughtsMessages.class);
    AppResources resources = GWT.create(AppResources.class);
    playComponentView = new PlayComponentView(playBinder, messages, resources);
    assertNotNull(playComponentView);

@lynx-r
Copy link
Author

lynx-r commented Nov 16, 2015

LienzoPanel can be created as GWT.create(LienzoPanel.class) and new LienzoPanel(width, height).

@scorpfrog
Copy link

scorpfrog commented Aug 1, 2016

I was having the same problem, but adding:

@WithClassesToStub(RootPanel.class)

Fixed it, thanks @ekuefler

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants