5

ウィジェットをテストせずに、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() }
    }
}

そして、私は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)

別のスタック オーバーフローの質問と簡単な調査に基づいて、これはこのプロジェクトで使用されている JUnit のバージョンに関係していると思われます。GwtMockito はBlockJunit4ClassRunner、@since 4.5 とマークされた を使用します。

では、このテストは GWTMockito が支援するようなものでしょうか? 私は GWTMockito をまったく初めて使用するので、簡単な誤解を招く可能性がありますが、理解したいと思います。

GWTMockito を使用して、Composite/を使用して小さなウィジェットから構築された複雑なウィジェットをテストできますIsWidgetか? GWTMockito はこの JSNI の問題を解決するのに役立ちましたか? テストランナーを使用していないからですか?

4

1 に答える 1

5

私の見方では、2つの可能性があります。

  1. GwtMockito の JUnit ランナーを使用するのを忘れました:

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

    別の方法で GwtMockito をセットアップできます。別の方法でカスタム ランナーが必要な場合。

  2. GWT.createウィジェットのインスタンス化に使用していません。

最初のポイントは簡単です。このランナーは、GwtMockito がその「魔法」を実行できるようにするために必要です。

2 番目の点については説明が必要です。GwtMockito は、GWT のDeferred Bindingを使用して動作します。つまり、GwtMockito によって自動的にモックされるすべてのウィジェットは、への呼び出しによってインスタンス化される必要GWT.createがあります。これは UiBinder では簡単です。内部では、UiBinder のテンプレートで定義されたすべてのウィジェットが でインスタンス化されるGWT.createため、GwtMockito で使用するために何も変更する必要はありません。しかし、UiBinder を使用していない (またはprovidingウィジェットの独自のインスタンスを使用している) 場合、ウィジェットを .xml でインスタンス化しない限り、GwtMockito はその魔法を働かせることができませんGWT.create

GwtMockitoのドキュメントから(強調鉱山):

GwtMockitoは、JUnit テストからGWT.createを呼び出して Mockito モックを返すことで、この問題やその他の GWT 関連のテストの問題を解決します。


アップデート

JUnit 4.4 では、ランナーがあなたが言及した例外をスローしていることを確認できます。これについては、GwtMockito のトラッカーで問題を作成しました。

テスト自体に関しては、なんとか機能させることができました。前に述べたように、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 で行う方法)、テストでモック (mockまたはから作成) を割り当てます。GWT.create
  • UiBinder に切り替えます;/

あまり魅力的なものはありませんが、最初のものが一般的に最高のようです.

于 2014-10-12T11:04:45.837 に答える