浏览 2005 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-10-23
使用Abbot给Java Swing写单元测试,遇到这样一个问题:如果用到了showDialog(...)方法,由于是ModelDialog,系统执行到这里就被block了,无法通过Abbot写单元测试。 举个简单的例子来说:Frame中有个button,点击后会显示JColorChooser Dialog,选取颜色后点击OK或者Cancel按钮,Dialog消失,同时返回Color对象,然后就可以在frame中修改Label的颜色。 所以想象中的单元测试应该是这样: @Test public void testSelectColorRedAndClickOKButton() throws Exception { FrameDemo demo = new FrameDemo(); demo.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); demo.pack(); demo.setVisible(true); JButton colorButton = (JButton) getFinder().find(demo, new ClassMatcher(JButton.class)) new JMenuItemTester().actionClick(colorButton);//1. Here will block after JColorChooser shows // 2. Some action to select color red: JColorChooserTester().actionSelectColor(Color.red) JLabel label = (JLabel) getFinder().find(demo, new ClassMatcher(JButton.class)) assertEquals(Color.red, label.getForeground()); } 类FrameDemo很简单: public class FrameDemo extends JFrame{ public void FrameDemo(){ JLabel label = new JLabel("Text color will change after you select new color"); label.setForeground(Color.black); JButton colorButton = new JButton("Choose Color..."); JPanel panel = new JPanel(); panel.add(label); panel.add(colorButton); this.setContentPane(panel); } } 但是有两个问题: 1.注释1所在地方,当JColorChooser Dialog显示之后线程就被block了; 2.Abbot中没有类JColorChooserTester帮助选择颜色。
根据以上考虑,决定自己写一个JColorChooserTester,完成以下功能: 1.根据输入选择颜色,并点击OK按钮关闭对话框; 2.可以不选取颜色直接点击Cancel按钮关闭对话框; 3.应该在显示对话框之前就调用该方法。 根据这些分析,对上面的测试做了修改: @Test public void testSelectColorRedAndClickOKButton() throws Exception { FrameDemo demo = new FrameDemo(); demo.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); demo.pack(); demo.setVisible(true); JButton colorButton = (JButton) getFinder().find(demo, new ClassMatcher(JButton.class)); new JColorChooserTester().actionSelectColor(demo, Color.red);// We want dialog to return red new JMenuItemTester().actionClick(colorButton); JLabel label = (JLabel) getFinder().find(demo, new ClassMatcher(JButton.class)); assertEquals(Color.red, label.getForeground()); } 测试写完了,接下来就写JColorChooserTester类,上面的测试能够通过,并经过简单的重构后:
package com.tw.ui.tester; import abbot.finder.BasicFinder; import abbot.finder.Matcher; import abbot.finder.ComponentNotFoundException; import abbot.finder.MultipleComponentsFoundException; import abbot.finder.matchers.ClassMatcher; import abbot.tester.JComponentTester; import abbot.tester.JMenuItemTester; import javax.swing.*; import java.awt.*; import org.apache.log4j.Logger; public class JColorChooserTester extends JComponentTester { private static final long DEFAULT_TIME_OUT_IN_MILLISECONDS = 5000; private long waitInMilliSeconds; private Logger logger = Logger.getLogger(JColorChooserTester.class); public JColorChooserTester() { this(DEFAULT_TIME_OUT_IN_MILLISECONDS); } public JColorChooserTester(long waitInMilliSeconds) { this.waitInMilliSeconds = waitInMilliSeconds; } public void actionClickCancel(final Container container) { final JColorChooserFinder chooserFinder = new JColorChooserFinder(container); Thread thread = new Thread(){ public void run(){ new JMenuItemTester().actionClick(chooserFinder.getCancelButton()); } }; thread.start(); } public void actionSelectColor(Container container, final Color returnedColor) { final JColorChooserFinder chooserFinder = new JColorChooserFinder(container); Thread thread = new Thread(){ public void run(){ chooserFinder.getColorChooser().setColor(returnedColor); new JMenuItemTester().actionClick(chooserFinder.getOKButton()); } }; thread.start(); } class JColorChooserFinder { JColorChooser colorChooser; JButton cancelButton; JButton okButton; private boolean shouldWaitForDialog = true; long start = System.currentTimeMillis(); public JColorChooserFinder(Container container) { FindDialog(container); } private void FindDialog(final Container container) { SwingUtilities.invokeLater(new Runnable() { public void run() { try { JDialog dialog = waitAndFindDialog(container); if (dialog != null) { logger.debug("Find JColorChooser Dialog."); cancelButton = findCancelButton(dialog); okButton = findOKButton(dialog); colorChooser = findColorChooser(dialog); } } catch (Exception e) { } finally { shouldWaitForDialog = false; } } }); } private JDialog waitAndFindDialog(final Container container) { JDialog dialog = null; long waited = 0; while (dialog == null && shouldWaitMore(waited)) { try { dialog = (JDialog) new BasicFinder().find(container, new ClassMatcher(JDialog.class)); } catch (ComponentNotFoundException e) { } catch (MultipleComponentsFoundException e) { logger.debug("Found multiple JDialogs"); break; } waited += waitMore(500); } return dialog; } public JButton getCancelButton() { long waited = 0; while (shouldWaitForDialog && shouldWaitMore(waited)) { waited += waitMore(500); } return cancelButton; } private long waitMore(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { } return millis; } public JButton getOKButton() { long waited = 0; while (shouldWaitForDialog && shouldWaitMore(waited)) { waited += waitMore(500); } return okButton; } public JColorChooser getColorChooser() { long waited = 0; while (shouldWaitForDialog && shouldWaitMore(waited)) { waited += waitMore(500); } return colorChooser; } private JButton findCancelButton(JDialog dialog) { return findButtonByText(dialog, UIManager.getString("ColorChooser.cancelText")); } private JButton findOKButton(JDialog dialog) { return findButtonByText(dialog, UIManager.getString("ColorChooser.okText")); } private JColorChooser findColorChooser(JDialog dialog) { try { return (JColorChooser) new BasicFinder().find(dialog, new ClassMatcher(JColorChooser.class)); } catch (Exception e) { return null; } } private JButton findButtonByText(JDialog dialog, final String cancelString) { try { return (JButton) new BasicFinder().find(dialog, new Matcher() { public boolean matches(Component component) { return component.getClass().equals(JButton.class) && ((JButton) component).getText().equals(cancelString); } }); } catch (Exception e) { return null; } } private boolean shouldWaitMore(long waited) { return waited < waitInMilliSeconds; } } } JColorChooserTester的源码和测试代码请见附件。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |