测试拖放文件到应用程序

我正在寻找一种方法,通过unit testing将文件/多个文件拖放到我的应用程序中。 例如,在Windows资源管理器中选择一些文件,将它们拖放到我的应用程序中。

我能够在我的应用程序中测试两个组件之间的拖放行为(见下文 – 随意指出你是否知道更好的方法),但我不知道如何在数据必须来自时做同样的事情在我的申请之外。

当我手动执行拖放操作时,我想过使用调试器检查’文件’ 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将我的代码片段更新为’假’拖放。 该代码还包含一个主程序,它只创建一个空框架,您可以在其上删除文件。 然后路径将打印在控制台上。

在我的电脑上,文件的拖放不使用javaFileListFlavor而是使用URI风格。 以前的经验(参见这个问题 )已经告诉我,当从Java应用程序外部拖东西时, Transferable一个组件可能会以微妙的方式有所不同。

所以要完全清楚:我想测试我的代码中从收到的Transferable中提取信息的部分。 “信息处理”代码(例如,当应用程序收到文件时会发生什么)可以轻松地进行测试,而无需费心去做。 我只需要确保从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 fileList = ( List ) 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 ); } } ); } } 

unit testingSwing GUI总是很痛苦,更不用说D&D了。 但是,我相信它可以做到。

有两件事需要注意:

  1. 目前,您根本不测试D&D,而是复制粘贴。 这也是一种数据传输forms,但使用copyActionpasteAction会导致您真正无法完成D&D的任何步骤

  2. 你提到要检查接收文件的部分,因此你创建了一个自定义Transferable,但我想说你试图测试错误的东西。 处理数据的部分可以实现为处理包含数据的Transferable的包私有方法,并使用简单的unit testing进行测试(不涉及Swing组件)

我相信你应该测试的是,如果你关心不同操作系统之间的D&D差异,那就是D&D过程本身是有效的,即:

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

您可以使用FESTComponentDragAndDrop类来测试它(请参阅此处 )。

如果你想编写自己的实现(为什么要这样做?!)你可以:
用模拟(或间谍更准确)替换源组件和目标组件的TransferHandler ,除了调用实际方法之外,还可以validation是否使用预期数据调用了预期的方法

如果您不仅限于unit testing,您可以尝试编写GUI测试。 Swing有几个框架,请参阅此主题 – Swing UI的unit testing框架

几年前我一直在使用jemmy一段时间,如果测试很简单就没关系

也许AutoIt Script可以提供帮助: 请看这里

您可以创建一个Windows脚本来模拟必要的鼠标或键事件。 然后从您测试中运行此脚本,看看会发生什么。

希望这可以帮助。

你见过机器人课吗? 测试人机交互非常酷。 我不知道你是否可以拖放文件..但你有意义!

您可以使用Swinput在Linux上模拟输入事件。

尝试使用模拟。 我正在使用Mockito框架。