14

TotalCommander のようなアプリケーションを作成しています。ファイルリスト用の別のコンポーネントと、そのモデルがあります。モデルはリスナーをサポートCurrentDirChangedし、次のようなイベントの通知を発行します。

private void fireCurrentDirectoryChanged(最終 IFile dir) {
    if (SwingUtilities.isEventDispatchThread())
        for (FileTableEventsListenerリスナー: tableListeners)
            listener.currentDirectoryChanged(dir);
    そうしないと {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                for (FileTableEventsListenerリスナー: tableListeners)
                    listener.currentDirectoryChanged(dir);
            }
        });
    }
}

私はこれのための簡単なテストを書きました:

@テスト
public void testEvents() は IOException をスローします {
    IFile testDir = mockDirectoryStructure();
    最終的な FileSystemEventsListener リスナー =
                context.mock(FileSystemEventsListener.class);
    context.checking(new Expectations() {{
        oneOf(listener).currentDirectoryChanged(with(any(IFile.class)));
    }});

    FileTableModel モデル = 新しい FileTableModel(testDir);
    model.switchToInnerDirectory(1);
}

がないため、これは機能しませんEventDispatchThread。ヘッドレスビルド内でこれを単体テストする方法はありますか?

単体テストJavaスイングjmock

4

5 に答える 5

13

一般的に言うと、UI に関する単体テストは、利用できない多くのものをモック化する必要があるため、常に困難です。
したがって、(あらゆるタイプの) アプリケーションを開発する際の主な目的は、UI の要素をメインのアプリケーション ロジックからできるだけ分離することです。ここに強い依存関係があると、単体テストが非常に難しくなり、基本的に悪夢になります。これは通常、 MVCのようなアプローチのようなパターンを使用して活用されます。この場合、主にコントローラー クラスをテストし、ビュー クラスは UI を構築し、アクションとイベントをコントローラーに委譲するだけです。これにより、責任が分離され、テストが容易になります。

さらに、イベントが正しく発生するかどうかのテストなど、フレームワークによって既に提供されているものを必ずしもテストする必要はありません。書いているロジックを自分でテストするだけです。

于 2009-09-26T09:46:03.970 に答える
11

これを見てください:

FEST は、 Apache 2.0 ライセンスの下でリリースされたライブラリのコレクションであり、その使命はソフトウェア テストを簡素化することです。TestNGまたはJUnitで使用できるさまざまなモジュールで構成されています...

于 2009-09-26T11:48:25.953 に答える
2

uispec4j プロジェクトを確認してください。これは、UI のテストに使用するものです。

www.uispec4j.org

于 2009-09-29T11:40:52.870 に答える
2

テストの問題は、コードの問題を明らかにしていると思います。モデルがディスパッチ スレッドで実行されているかどうかを判断するのは、実際にはモデルの仕事であってはなりません。責任が多すぎます。通知ジョブを実行するだけで、呼び出し元のコンポーネントに直接呼び出すか、invokeLater にするかを決定させる必要があります。そのコンポーネントは、Swing スレッドを認識しているコードの一部にある必要があります。このコンポーネントは、ファイルなどについてのみ知っている必要があります。

于 2009-09-30T12:36:13.670 に答える
1

jMock を使ってまだ 2 日しか経っていないので、もっと洗練された解決策があればすみません。:)

あなたの FileTableModel は SwingUtilities に依存しているようです...使用する SwingUtilities をモックすることを検討しましたか? ハックのように思えますが、問題を解決する 1 つの方法は、ISwingUtilities などのインターフェイスを作成し、実際の SwingUtilities に転送するだけのダミー クラス MySwingUtilities を実装することです。次に、テスト ケースでインターフェイスをモックアップし、isEventDispatchThread に対して true を返すことができます。

@Test
public void testEventsNow() throws IOException {
    IFile testDir = mockDirectoryStructure();

    final ISwingUtilities swingUtils = context.mock( ISwingUtilities.class );

    final FileSystemEventsListener listener = 
                context.mock(FileSystemEventsListener.class);

    context.checking(new Expectations()
    {{
        oneOf( swingUtils ).isEventDispatchThread();
            will( returnValue( true ) );

        oneOf(listener).currentDirectoryChanged(with(any(IFile.class)));
    }});

    FileTableModel model = new FileTableModel(testDir);
    model.setSwingUtilities( swingUtils ); // or use constructor injection if you prefer
    model.switchToInnerDirectory(1);
}
于 2009-09-30T04:55:04.997 に答える