gpt4 book ai didi

gwt - GWTMockito UnsatisfiedLinkError

转载 作者:行者123 更新时间:2023-12-01 02:14:20 24 4
gpt4 key购买 nike

我已经完成了大部分GWT MVP风格的测试,而没有测试小部件。我希望能够构建更复杂的小部件并对其进行良好的测试,而无需使用GwtTestCase(缓慢)。

出于好奇,我尝试了一个非常简单的测试。给一个非常简单的小部件,就像这样(这不是我的确切类,只是一个简化的示例):

public class MyWidget extends Composite {
private TextBox boxOne, boxTwo;

public MyWidget() {
boxOne = new TextBox();
boxTwo = new TextBox();
VerticalPanel panel = new VerticalPanel();
panel.add( boxOne );
panel.add( boxTwo );
initWidget( panel );
}

public String[] getText() {
return new String[] { boxOne.getText(), boxTwo.getText() }
}
}


我正在使用GWTMockito测试,如下所示:

public class MyWidgetTest {

private ConstantsWithLookup constants;
private MyWidget widget;

@Before
public void createMocks() {
GwtMockito.initMocks( this );
constants = mock( ConstantsWithLookup.class );
}

@Test
public void testIsInvalidByDefault() {
widget = new MyWidget( constants ) {
protected void initWidget(Widget w) {
// Disarm for testing
}
};
assertNotNull( widget );
}

@After
public void tearDown() {
GwtMockito.tearDown();
}

}


我立即得到:

java.lang.UnsatisfiedLinkError: com.google.gwt.dom.client.Document.nativeGet()Lcom/google/gwt/dom/client/Document;
at com.google.gwt.dom.client.Document.nativeGet(Native Method)
at com.google.gwt.dom.client.Document.get(Document.java:46)
at com.google.gwt.user.client.ui.TextBox.<init>(TextBox.java:78)
at mypackage.MyWidget.<init>(MyWidget.java:linenumber)
... etc ...


您会注意到我没有使用测试运行器,但是我正在测试,但是我正在测试的项目使用的是JUnit 4.4,测试运行器似乎不适用于JUnit 4.4。如果使用GwtMockitoTestRunner,则会得到:

java.lang.NoSuchFieldError: NULL
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:57)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:57)
at com.google.gwtmockito.GwtMockitoTestRunner.<init>(GwtMockitoTestRunner.java:114)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)


基于 another stack overflow question和快速的调查,我倾向于认为这与该项目中使用的JUnit版本有关。 GwtMockito使用 BlockJunit4ClassRunner,从4.5开始被标记为@。

那么,此测试是GWTMockito应该帮助的事情吗?我对GWTMockito完全陌生,因此很容易造成一个简单的误解,但我想了解。

我可以使用GWTMockito测试使用 Composite / IsWidget从较小的小部件构建的复杂小部件吗? GWTMockito是否应该帮助我解决JSNI问题,或者我读错了什么?仅仅是因为我没有使用测试运行器吗?

最佳答案

从我的角度来看,有两种可能性:


您忘记使用GwtMockito的JUnit运行器:

@RunWith(GwtMockitoTestRunner.class)
public class MyTest {
// ...
}


如果您需要其他自定义运行器,则可以在 alternative way中设置GwtMockito。
您没有使用 GWT.create实例化窗口小部件。


第一点很简单-需要该运行程序,以便GwtMockito可以执行其“魔术”。

第二点需要解释:GwtMockito通过使用GWT的 Deferred Binding起作用。这意味着,要通过GwtMockito自动模拟的所有小部件都必须通过调用 GWT.create实例化。对于UiBinder来说,这很简单-内部,UiBinder模板中定义的所有小部件都使用 GWT.create实例化,因此您无需进行任何更改即可将其与GwtMockito一起使用。但是,如果您不使用UiBinder(或者是 providing您自己的窗口小部件实例),则除非您使用 GWT.create实例化窗口小部件,否则GwtMockito将无法发挥其魔力。

GwtMockito's documentation(重点是我):


GwtMockito通过允许您从JUnit测试调用GWT.create并返回Mockito模拟,解决了此问题以及其他与GWT相关的测试问题。




更新资料

我可以使用JUnit 4.4验证运行程序是否抛出了您提到的异常。我为此打开了 issue on GwtMockito's tracker

至于测试本身,我设法使其能够正常工作。如前所述,GwtMockito的工作归功于Deferred Binding。意味着,您的窗口小部件也必须使用 GWT.create实例化-成员也是如此。这就是GwtMockito进入小部件的“方式”。如果仅调用 new TextBox(),则无法用模拟代替它。
如果将MyWidget类更改为以下类,它将通过测试(请注意对 GWT.create的调用)。

public class MyWidget extends Composite {
private TextBox boxOne, boxTwo;

public MyWidget() {
boxOne = GWT.create(TextBox.class);
boxTwo = GWT.create(TextBox.class);
VerticalPanel panel = GWT.create(VerticalPanel.class);
panel.add( boxOne );
panel.add( boxTwo );
initWidget( panel );
}

public String[] getText() {
return new String[] { boxOne.getText(), boxTwo.getText() };
}
}


知道这一点,有一些选择:


永远记得使用 GWT.create实例化合成中的所有小部件
将它们公开为可见的包(在UiBinder中的操作方式),并在测试中为它们分配模拟(从 mockGWT.create创建)
切换到UiBinder; /


似乎没有一个吸引人,第一个似乎总体上最好。

关于gwt - GWTMockito UnsatisfiedLinkError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26308676/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com