5

YES私は、ユーザーが選択するかNO、から選択することを期待するJavaSwingアプリケーションを持っていますJOptionPane.showConfirmDialog

JOptionPaneはスレッドを停止し、ユーザー入力を待機しているため、私のコードは自動的にテストできません。

とにかく私はこれをプログラムで回避することができますか?または、はいまたはいいえをシミュレートしますか?

今の私のテストでは、確認ダイアログが表示され、[はい]または[いいえ]ボタンを押す必要があります。

アップデート

素晴らしいオプションを見つけました。

OptionPane基本的に必要なすべての種類のメッセージで呼び出されるインターフェイスを作成しました。次に、JOptionPaneの静的メソッドに委任するだけのデフォルトの実装を作成しました。次に、YesMockOptionPaneを作成しました。これは、基本的にすべての確認メッセージに対してYES_OPTIONを返し、すべてのNO_OPTIONSに対してNoMockOptionPaneを返します。

コードは次のとおりです。

<<usage>>

class Foo {
  OptionPane optionPane = new DefaultOptionPane();

  public void someMethod() {
    if (optionPane.showConfirmDialog(null, "choose yes or no", "Please confirm", 
                    JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION)
                return;

        //User pressed yes
  }    

  public void setOptionPane(OptionPane o) {
    this.optionPane = o;
  }
}

//Snippet of the interface
public interface OptionPane {

   int showConfirmDialog(Component parentComponent,
          Object message, String title, int optionType);
}

public class DefaultOptionPane implements OptionPane {
  @Override
  public int showConfirmDialog(Component parentComponent,
        Object message, String title, int optionType) {

      return JOptionPane.showConfirmDialog(parentComponent,message,title,optionType);
  }
}

public class YesMockOptionPane extends DefaultOptionPane {
  //MockOptionPane is just an abstract class implementing default methods from OptionPane
  @Override
  public int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) {
      return JOptionPane.YES_OPTION;
   }
}

これで、単体テストで適切なMockOptionPaneを設定するだけで済みます。

dialog.setOptionPane(new YesMockOptionPane());
4

3 に答える 3

3

エレガントな方法は、次のようなインターフェイスからの回答を期待するようにコードを変更することです。

public interface UserAnswer {
    boolean yesPressed();
}

次に、本番コードの場合はJOptionPane.showConfirmDialogを使用して実装し、テストコードの場合はハードコードします。

これが不可能な場合は、EventQueue.invokeLaterを使用してイベントディスパッチスレッドのイベントをJOptionPaneに送信してみてください。

于 2012-07-17T12:43:22.303 に答える
3

これは私が思いついた解決策です(質問にもコピーされています)

<<usage>>

class Foo {
  OptionPane optionPane = new DefaultOptionPane();

  public void someMethod() {
    if (optionPane.showConfirmDialog(null, "choose yes or no", "Please confirm", 
                    JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION)
                return;

        //User pressed yes
  }    

  public void setOptionPane(OptionPane o) {
    this.optionPane = o;
  }
}

//Snippet of the interface
public interface OptionPane {

   int showConfirmDialog(Component parentComponent,
          Object message, String title, int optionType);
}

public class DefaultOptionPane implements OptionPane {
  @Override
  public int showConfirmDialog(Component parentComponent,
        Object message, String title, int optionType) {

      return JOptionPane.showConfirmDialog(parentComponent,message,title,optionType);
  }
}

public class YesMockOptionPane extends MockOptionPane {

  @Override
  public int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) {
      return JOptionPane.YES_OPTION;
   }
}

単体テストでは、適切な MockOptionPane を設定するだけです。

dialog.setOptionPane(new YesMockOptionPane());
于 2012-07-17T13:04:08.593 に答える
1

これについては既存の答えがあると思いましたが、見つかりませんでした。

コードとJOptionPaneの間に抽象化レイヤーを作成する必要があると思います。
これは、ユーザーがyesまたはnoを選択したかどうかに関係なく、コードに戻るメソッドを備えたインターフェイスの形式である必要があります。メソッドは、「isWantToOverwriteExistingFile」などの意味のあるものを呼び出すことができます。

このインターフェースの通常の実装では、現在行っているようにJOptionPaneが呼び出されます。
テストでは、このインターフェイスの異なる実装を使用します。これは、テストで行う選択に応じて、(JOptionPaneを表示せずに)yesまたはnoを返します。

詳細が必要な場合はお知らせください。

于 2012-07-17T12:44:00.933 に答える