【发布时间】:2016-02-06 18:57:23
【问题描述】:
这里的上下文是单元测试:在测试结束时,在tearDown,如果JFileChooser 被“挂起”(即显示),我想强制它以“取消”返回价值。
问题是,否则,我调用showOpenDialog(一种阻塞方法)的actionPerformed() 继续存在......我需要关闭那个Runnable。
注意 Runnable 运行 actionPerformed 当然是在 EDT 中运行。但是尽管如此,该框架还是能够启动另一个“事件泵”:我的理解是,当您在 EDT 中执行 JFileChooser.showOpenDialog 时,这是非常正常和正确的行为:类似于调用 JOptionPane.showXXX 静态方法之一在美国东部时间。
我还想避免“测试人为”的解决方案:换句话说,应用程序代码必须足以满足自身需求,并且不使用曲折或不自然的机制,因为它知道它将通过测试运行需要为其提供“句柄”的代码。
PS 我实际上使用的是 Jython,而不是 Java,而且我使用的是 Python unittest 模块,而不是基于 Java 的单元测试框架。但这并没有改变所涉及的原则......
PPS (稍后) 我设计了一种我认为相当“不稳定”的方法:这涉及深入挖掘JFileChooser 以识别JButton getText() == "取消"。抱歉,它是用 Jython 编写的,但即使是不懂 Python 的人也应该很容易掌握:
def close_main_frame():
self.main_frame.dispose()
self.cancel_button = None
def explore_descendant_comps( container, method, breadth_first = False, depth = 0 ):
for component in container.components:
if isinstance( component, java.awt.Container ):
if breadth_first:
method( component, depth )
explore_descendant_comps( component, method, breadth_first, depth + 1 )
if not breadth_first:
method( component, depth )
def identify_cancel_button( comp, depth ):
if isinstance( comp, javax.swing.JButton ) and comp.text == 'Cancel':
self.cancel_button = comp
explore_descendant_comps( self.main_frame.analysis_file_chooser, identify_cancel_button )
if self.cancel_button:
self.cancel_button.doClick()
else:
raise Exception()
self.edt_despatcher.run_in_edt( close_main_frame, False )
这是“不稳定的”,尤其是因为按钮的“取消”文本可能会被另一种语言的其他名称替换...
【问题讨论】:
-
其实选择器上有一个cancelSelection()方法。如果你有组件,你不能直接调用吗?可能你需要在调用它之前检查组件上的 instanceOf JFileChooser。
-
是的...看我的第二条评论...谢谢!
-
对于涉及 UI 的测试,您需要 FEST code.google.com/archive/p/fest 之类的东西。
-
@Michal 感谢您的链接:有趣。问题是,我使用的是 Jython 和 Python unittest 模块,而不是 Java 单元测试框架。当您在单元测试框架中进行 EDT 时,您肯定是对的,事情变得非常具有挑战性。事实上,Jython 需要自己的东西,尤其是因为 Jython 与标准 CPython(只是开玩笑)不同,它是多线程的,并且涉及 EDT。我正在逐渐发展我自己的一系列技术......其优势在于我了解它实际上在做什么!
-
AFAIK 无论使用哪种单元测试框架,您都可以使用 FEST。 FEST 只是一个允许编写代码进行用户交互的库 - 单击(JB)按钮,在(JT)文本字段中输入文本等等。它类似于用于 Web UI 的 Selenium。
标签: java multithreading unit-testing jython jfilechooser