首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在应用程序上测试拖放文件

在应用程序上测试拖放文件
EN

Stack Overflow用户
提问于 2012-08-02 06:08:17
回答 6查看 3.1K关注 0票数 18

我正在寻找一个方法来执行拖放一个文件/多个文件到我的应用程序从一个单元测试。例如,在Windows中选择一些文件,将它们拖放到我的应用程序中。

我能够测试我的应用程序中两个组件之间的拖放行为(请参阅下面--请放心,如果您知道更好的方法),但是当数据必须来自我的应用程序之外时,我不知道如何做。

当我手工执行拖放操作时,我考虑使用调试器检查“文件”Transferable,但是肯定有比硬编码完整的Transferable更好的方法。

组件之间的拖放测试示例

代码语言:javascript
复制
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上,文件的拖放不是使用javaFileListFlavor,而是使用URI。以前的经验(请参阅这个问题)已经告诉我,组件在从Java应用程序外部拖动某些东西时接收的Transferable可能有细微的不同。

因此,要完全清楚:我想测试代码中从接收到的Transferable中提取信息的部分。‘信息处理’代码(例如,当应用程序接收到文件时会发生什么)可以很容易地进行测试,而无需使用D&D。我只需要确保从Transferable中提取正确的信息,用硬编码的Transferable来测试它是愚蠢的。

代码语言:javascript
复制
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 );
      }
    } );
  }
}
EN

回答 6

Stack Overflow用户

发布于 2014-08-13 08:05:07

单元测试Swing GUI总是痛苦的,更不用说D&D了,然而,我相信它是可以做到的。

有两件事需要注意:

  1. 目前,您根本没有测试D&D,而是复制粘贴。这也是数据传输的一种形式,但是copyActionpasteAction的使用导致您实际上没有经历任何D&D的步骤。
  2. 您提到您希望检查接收文件的部分,因此您创建了一个自定义可转移的部分,但我想说的是,您试图测试错误的内容。处理数据的部分可以实现为处理包含数据的Transferable的包私有方法,并使用简单的单元测试(不涉及Swing组件)进行测试。

我认为,如果您关心不同操作系统之间的D&D差异,您应该测试的是,D&D流程本身正在工作,即:

  1. 请求具有数据的组件( DragSource)提供数据,并要求它提供数据。
  2. 请求数据的组件( DropTarget)接收并处理数据。
  3. 或者,您可能需要检查是否允许或不允许不同的条件(例如复制和移动,等等)。

您可以使用FESTComponentDragAndDrop类进行测试(参见这里)。

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

将源组件和目标组件的TransferHandler替换为模拟(或间谍更精确),在调用实际方法的基础上,将使您能够验证预期的方法是否使用预期的数据调用。

票数 1
EN

Stack Overflow用户

发布于 2012-08-09 09:50:52

如果不局限于单元测试,则可以尝试编写GUI测试。有几个Swing框架,请参阅这个线程- Swing UI的单元测试框架

几年前我就开始使用jemmy了,如果测试简单的话,这是可以的。

票数 0
EN

Stack Overflow用户

发布于 2012-10-03 10:29:02

也许AutoIt脚本可以帮上忙:看这里

您可以创建一个windows脚本来模拟必要的鼠标或键事件。然后从你的内部运行这个脚本,看看会发生什么。

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11771918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档