测试拖放到应用程序的文件 [英] Testing drag-and-drop files onto application

查看:133
本文介绍了测试拖放到应用程序的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种从单元测试中将文件/多个文件拖放到我的应用程序上的方法。例如在Windows资源管理器中选择一些文件,将其拖放到我的应用程序中。

I am looking for a method to perform a drag-and-drop of a file/multiple files onto my application from a unit test. For example selecting some files in Windows Explorer, drag them and drop them on my application.

我有能力测试应用程序中两个组件之间的拖放行为(见下文 - 自由地表明如果你知道更好的方式),但是当数据来自我的应用程序之外,我不知道如何做同样的事情。

I am capable of testing drag-and-drop behavior between two components in my application (see below - feel free to indicate if you know a better way), but I have no idea how to do the same when the data has to come from outside my application.

当我手动进行拖放操作时,我考虑使用调试器来检查'code>可转移的文件,但必须有一个更好的方法,然后硬 - 编写一个完整的可转移

I thought about using the debugger to inspect a 'file' Transferable when I do the drag-and-drop operation by hand, but there must be a better way then hard-coding a complete Transferable.

组件之间的拖放测试示例

Example of a drag-and-drop test between components

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() );
  }
}

修改

根据这个问题的意见,我已经通过提供一个硬编码的可传递的将我的代码片段更新为假拖放/ code>。该代码还包含一个主程序,只需创建一个可以放置文件的空框架。路径将被打印在控制台上。

Based on the comments under this question, I have updated my code snippet to 'fake' a drag-and-drop by providing a hard-coded Transferable. The code also contains a little main program which just creates an empty frame on which you can drop files. The path will then be printed on the console.

在我的电脑上,拖放文件不使用 javaFileListFlavor 而是URI的味道。
以前的经验(请参阅此问题)已经告诉我,当从Java应用程序外部拖动某些东西时,组件接收的可传递可能会有微妙的差异。

On my PC, drag-and-drop of a file does not use the javaFileListFlavor but the URI flavor. Previous experiences (see this question) already teached me that the Transferable a component receives when dragging something from outside the Java application might differ in subtle ways.

所以要完全清楚:我想测试我的代码部分,从收到的可转移中提取信息。 信息处理代码(例如,当应用程序接收文件时会发生什么)可以很容易地进行测试,而不用D&D。我只需要确保从可转让中提取正确的信息,而且用硬编码的可转让

So to be completely clear: I want to test the part of my code that extracts the information from the received Transferable. The 'information-handling' code (e.g. what happens when the application receives the file) can easily be tested without bothering with D&D. I just need to make sure I extract the correct information from the Transferable, and it is silly to test this with a hard-coded 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 );
      }
    } );
  }
}


推荐答案

测试Swing GUI总是很痛苦,更不用说D&D。但是,我相信可以做到。

Unit-testing Swing GUI is always painful, let alone D&D. However, I believe it can be done.

有两件事要注意:


  1. 目前,你根本没有测试D&D,而是复制粘贴。这也是一种数据传输形式,但是使用 copyAction pasteAction 使您真的不会经历任何D&D的步骤

  1. Currently, you're not testing D&D at all, but rather copy-paste. This is also a form of data transfer, but the use of copyAction and pasteAction causes you to really not go through any of the steps of D&D

您提到要检查接收文件的部分,因此您创建了一个自定义可转移,但我会喜欢争论你试图测试错误的东西。处理数据的部分可以作为处理包含数据的可传递的包私有方法实现,并通过简单的单元测试进行测试(不涉及Swing组件)

You mention that you want to check the part that receives the file, and therefore you created a custom Transferable, but I would like to argue that you're trying to test the wrong thing. The part that handles the data can be implemented as a package private method handling a Transferable containing the data, and tested with a simple unit test (no Swing components involved)

我相信你应该测试什么,如果你关心不同操作系统之间的D&D差异,那么D& D进程本身正在工作,即:

I believe that what you should be testing, if you care about D&D differences between different OS, is that the D&D process itself is working, i.e.:


  1. 具有数据的组件( DragSource )被请求提供数据,并且它提供它

  2. 请求数据的组件( DropTarget )接收数据并且处理它

  3. 您可能需要检查是否允许或不允许不同的条件(例如复制与移动等)。

  1. The component with the data (the DragSource) is requested to provide the data, and that it provides it
  2. The component requesting the data (the DropTarget) receives the data and handles it
  3. Optionally, you might want to check that different conditions are allowed or disallowed (e.g. copy vs. move, etc.)

您可以使用 FEST ComponentDragAndDrop 类(请参阅她e )。

You can test this by either using FEST's ComponentDragAndDrop class (see here).

如果你想写你自己的实现(为什么要这样做?!)你可以:

使用mocks(或间谍更准确)替换源组件和目标组件$ codeTransferHandler
,除了调用真实方法之外,还可以验证使用预期数据

If you want to write you own implementation (why would you want to do that ?!) you could:
Replace both the source and target components' TransferHandlers with mocks (or spies to be more accurate), that on top of calling the real methods, would enable you to verify that the expected methods are called with the expected data

这篇关于测试拖放到应用程序的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆