Geo*_*man 5 gwt mocking gwtmockito
我已经完成了 MVP 风格的大部分 GWT 测试,没有测试小部件。我希望能够构建更复杂的小部件并在不使用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() }
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 GWTMockito 测试,有点像这样:
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() }
}
}
Run Code Online (Sandbox Code Playgroud)
我立即得到:
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 ...
Run Code Online (Sandbox Code Playgroud)
您会注意到我没有使用测试运行程序——我尝试过,但我正在测试的项目使用的是 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)
Run Code Online (Sandbox Code Playgroud)
根据另一个堆栈溢出问题和快速调查,我倾向于相信这与该项目中使用的 JUnit 版本有关。GwtMockito 使用BlockJunit4ClassRunner
,标记为 @since 4.5。
那么,这个测试是 GWTMockito 应该帮助完成的事情吗?我对 GWTMockito 完全陌生,所以这很容易是一个简单的误解,但我想理解。
Composite
我可以使用 GWTMockito 来测试使用/从小部件构建的复杂部件吗IsWidget
?GWTMockito 不应该帮助我解决这个 JSNI 问题吗?还是我误读了什么?仅仅是因为我没有使用测试运行程序吗?
在我看来,有两种可能性:
您忘记使用 GwtMockito 的 JUnit 运行程序:
@RunWith(GwtMockitoTestRunner.class)
public class MyTest {
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果您需要自定义运行器用于其他用途,您可以以替代方式设置 GwtMockito 。
您不用GWT.create
来实例化您的小部件。
第一点很简单 - 需要这个运行程序,以便 GwtMockito 可以发挥其“魔力”。
第二点需要解释:GwtMockito 通过使用 GWT 的Deferred Binding来工作。这意味着,您想要由 GwtMockito 自动模拟的所有小部件都必须通过调用来实例化GWT.create
。这对于 UiBinder 来说很简单 - 在内部,UiBinder 模板中定义的所有小部件都使用 实例化GWT.create
,因此您无需更改任何内容即可将其与 GwtMockito 一起使用。但是如果您没有使用 UiBinder(或者是providing
您自己的小部件实例),GwtMockito 将无法发挥其魔力,除非您使用GWT.create
.
来自GwtMockito 的文档(重点是我的):
GwtMockito 通过允许您从 JUnit 测试调用GWT.create并返回 Mockito 模拟来解决此问题以及其他与 GWT 相关的测试问题。
我可以验证使用 JUnit 4.4,运行程序会抛出您提到的异常。我为此在 GwtMockito 的跟踪器上提出了一个问题。
至于测试本身,我已经设法让它发挥作用。正如我之前提到的,GwtMockito 的工作得益于延迟绑定。这意味着,您的小部件也必须使用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() };
}
}
Run Code Online (Sandbox Code Playgroud)
知道这一点后,有一些选择:
GWT.create
mock
或创建)GWT.create
没有一个看起来太有吸引力,第一个似乎总体上是最好的。
归档时间: |
|
查看次数: |
1888 次 |
最近记录: |