18

単体テストからアプリケーションに 1 つまたは複数のファイルをドラッグ アンド ドロップする方法を探しています。たとえば、Windows エクスプローラーでいくつかのファイルを選択し、それらをアプリケーションにドラッグ アンド ドロップします。

アプリケーションの 2 つのコンポーネント間のドラッグ アンド ドロップ動作をテストすることはできます (以下を参照してください。より良い方法を知っているかどうかを自由に示してください)。私のアプリケーションの外。

手でドラッグアンドドロップ操作を行うときに、デバッガーを使用して「ファイル」を検査することを考えましTransferableたが、完全な をハードコーディングするよりも良い方法があるはずTransferableです。

コンポーネント間のドラッグ アンド ドロップ テストの例

import org.junit.Test;

import javax.swing.Action;
import javax.swing.JTextField;
import javax.swing.TransferHandler;
import java.awt.event.ActionEvent;

import static org.junit.Assert.assertEquals;

public class DragAndDropTest {
  @Test
  public void dragAndDropBetweenTwoTextFields() {
    JTextField firstField = new JTextField();
    JTextField secondField = new JTextField();
    String testText = "Test text";
    firstField.setText( testText );
    firstField.selectAll();
    Action copyAction = TransferHandler.getCopyAction();
    copyAction.actionPerformed( new ActionEvent( firstField, ActionEvent.ACTION_PERFORMED, "Copy" ) );
    Action pasteAction = TransferHandler.getPasteAction();
    pasteAction.actionPerformed( new ActionEvent( secondField, ActionEvent.ACTION_PERFORMED, "Paste" ) );
    assertEquals( "Text is not copied", testText, secondField.getText() );
  }
}

編集

この質問の下のコメントに基づいて、コード スニペットを更新して、ハードコードされTransferableた . このコードには、ファイルをドロップできる空のフレームを作成するだけの小さなメイン プログラムも含まれています。パスはコンソールに表示されます。

私の PC では、ファイルのドラッグ アンド ドロップは ではなくjavaFileListFlavorURI フレーバーを使用します。以前の経験 (この質問を参照)Transferableから、Java アプリケーションの外部から何かをドラッグしたときに受け取るコンポーネントが微妙に異なる可能性があることがわかりました。

完全に明確にするために、受信した から情報を抽出するコードの部分をテストしたいと思いますTransferable。「情報処理」コード (たとえば、アプリケーションがファイルを受信したときに何が起こるか) は、D&D に煩わされることなく簡単にテストできます。から正しい情報を抽出することを確認する必要があるだけでTransferable、これをハードコードされた でテストするのはばかげていTransferableます。

import org.junit.Test;

import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class DragAndDropTest {
  private static DataFlavor URI_LIST_FLAVOR = null;
  static {
    try {
      URI_LIST_FLAVOR = new DataFlavor( "text/uri-list;class=java.lang.String" );
    }
    catch ( ClassNotFoundException ignore ) {
    }
  }

  @Test
  public void testFileDragAndDrop() throws IOException, UnsupportedFlavorException {
    JComponent testComponent = new JPanel();
    TestingTransferHandler transferHandler = new TestingTransferHandler();
    testComponent.setTransferHandler( transferHandler );
    Clipboard clipBoard = new JLabel(  ).getToolkit().getSystemClipboard();
    Transferable transferable = new Transferable() {
      @Override
      public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[]{URI_LIST_FLAVOR};
      }

      @Override
      public boolean isDataFlavorSupported( DataFlavor flavor ) {
        return flavor == URI_LIST_FLAVOR;
      }

      @Override
      public Object getTransferData( DataFlavor flavor ) throws UnsupportedFlavorException, IOException {
        if ( flavor == URI_LIST_FLAVOR ) {
          return new String( "file:///home/robins/Desktop/swingx-1.0-javadoc.jar" );
        }
        throw new UnsupportedFlavorException( flavor );
      }
    };
    clipBoard.setContents( transferable, null );
    Action pasteAction = TransferHandler.getPasteAction();
    pasteAction.actionPerformed( new ActionEvent( testComponent, ActionEvent.ACTION_PERFORMED, "Paste" ) );
    assertEquals( transferable.getTransferData( URI_LIST_FLAVOR ), transferHandler.transferable.getTransferData( URI_LIST_FLAVOR ) );
  }

  private static class TestingTransferHandler extends TransferHandler{
    public Transferable transferable;
    @Override
    public boolean canImport( TransferSupport support ) {
      return true;
    }
    @Override
    public boolean importData( TransferSupport support ) {
      transferable = support.getTransferable();
      try{
        if ( transferable.isDataFlavorSupported( DataFlavor.javaFileListFlavor ) ) {
          System.out.println("File list flavor");
          List<File> fileList = ( List<File> ) transferable.getTransferData( DataFlavor.javaFileListFlavor );
          System.out.println( "fileList = " + fileList );
        }
        if ( transferable.isDataFlavorSupported( URI_LIST_FLAVOR )){
          System.out.println("URI list flavor");
          String uriList = ( String ) transferable.getTransferData( URI_LIST_FLAVOR );
          System.out.println( "uriList = " + uriList );
        }
        return true;
      } catch ( UnsupportedFlavorException e ) {
        return false;
      } catch ( IOException e ) {
        return false;
      }
    }
  }

  public static void main( String[] args ) {
    EventQueue.invokeLater( new Runnable() {
      @Override
      public void run() {
        JFrame frame = new JFrame( "TestFrame" );
        JPanel contentPane = new JPanel( new BorderLayout(  ) );
        contentPane.setTransferHandler( new TestingTransferHandler() );
        frame.setContentPane( contentPane );
        frame.setSize( 200,200 );
        frame.setVisible( true );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      }
    } );
  }
}
4

6 に答える 6

1

Swing GUI の単体テストは、D&D はおろか、常に苦痛です。しかし、私はそれができると信じています。

注意すべき点が 2 つあります。

  1. 現在、D&D をまったくテストしておらず、コピー アンド ペーストを行っています。これもデータ転送の 1 つの形式ですが、 と を使用するcopyActionpasteAction、D&D の手順をまったく実行しなくなります。

  2. ファイルを受け取る部分を確認したいので、カスタム Transferable を作成したとのことですが、間違ったことをテストしようとしていると主張したいと思います。データを処理する部分は、データを含む を処理するパッケージ プライベート メソッドとして実装Transferableし、単純な単体テストでテストできます (Swing コンポーネントは関与しません)。

異なる OS 間の D&D の違いに関心がある場合、テストする必要があるのは、D&D プロセス自体が機能していることです。つまり、次のようになります。

  1. データを持つコンポーネント ( DragSource) は、データを提供するように要求され、データを提供すること
  2. データを要求するコンポーネント ( DropTarget) がデータを受け取り、それを処理します。
  3. 必要に応じて、さまざまな条件が許可または禁止されていることを確認することもできます (例: コピーと移動など)。

FESTComponentDragAndDropクラスを使用してこれをテストできます(こちらを参照)。

独自の実装を書きたい場合 (なぜそれをしたいのですか?!):
ソース コンポーネントとターゲット コンポーネントの両方TransferHandlerをモック (またはより正確にはスパイ) に置き換えて、実際のメソッドを呼び出します。 、期待されるメソッドが期待されるデータで呼び出されることを確認できます

于 2014-08-13T08:05:07.017 に答える
0

ロボットのクラスを見たことがありますか。人間の相互作用をテストするのはかなりクールです。ファイルをドラッグアンドドロップできるかどうかはわかりませんが、できることは理にかなっています。

于 2012-10-03T20:41:33.783 に答える
0

AutoItスクリプトが役立つかもしれません:こちらをご覧ください

Windows スクリプトを作成して、必要なマウスまたはキー イベントをシミュレートできます。次に、テスト内からこのスクリプトを実行し、何が起こるかを確認します。

お役に立てれば。

于 2012-10-03T10:29:02.040 に答える
0

単体テストに限定されていない場合は、GUI テストを作成してみることができます。Swing にはいくつかのフレームワークがあります。このスレッドを参照してください - Unit testing framework for a Swing UI

私は数年前からjemmyを使用していましたが、テストが簡単であれば問題ありませんでした

于 2012-08-09T09:50:52.500 に答える
0

Swinputを使用して、Linux で入力イベントをシミュレートできます。

于 2014-08-11T23:01:06.880 に答える
-1

モックを使用してみてください。Mockitoフレームワークを使用して います。

于 2012-10-07T21:10:24.193 に答える