【问题标题】:How to fire Swing GUI events for Unit Testing如何为单元测试触发 Swing GUI 事件
【发布时间】:2018-12-21 22:26:24
【问题描述】:

我正在使用 TDD 开发一个 Swing 应用程序。我的逻辑很好地解耦并通过监听焦点事件触发。但我无法以编程方式触发这些事件。

我认为field.requestFocus() 会触发focusGained(),但事实并非如此。我读过这可能是因为没有显示器。

import junit.framework.TestCase;
public class SomeClassTest extends TestCase{
    @Test
    public void testSomeMethod() {
        someLogic();
        for (JTextField field : fields[]){
            field.requestFocus();
            assertTrue(condition);
            ...
    }

如何触发“focusGained”和“focusLost”两个焦点事件?考虑到这是用于 junit 测试,没有 GUI 的选项会很棒。

编辑:使用答案中的模式我已经能够触发所有类型的 GUI 相关事件,希望它有所帮助。

【问题讨论】:

    标签: java swing unit-testing junit tdd


    【解决方案1】:

    我听说这可能是因为没有显示器。

    正确,只有可见 GUI 上的可见组件才能获得焦点。然后会自动生成 FocusEvent。

    没有 GUI 的选项会很棒。

    您也许可以使用:

    field.dispatchEvent(...);
    

    然后您将发送一个focusGained 事件。

    不知道这是否可行,或者dispatchEvent() 方法是否也检查了组件必须可见。

    【讨论】:

    • 尝试使用 field.dispatchEvent(new FocusEvent(field, FocusEvent.FOCUS_GAINED)); 并自行实例化焦点事件 new FocusEvent(field, FocusEvent.FOCUS_GAINED) 但仍然没有在侦听器上触发任何内容。太糟糕了,有什么方法可以模拟可见性,因为甚至没有触发 actionEvents,我最终可能会实现自己的非 gui 事件,但我宁愿使用 swing 中的内置函数
    • Is there any way to mock the visibility - 它可能不仅仅是可见性。还有像“isDisplayable()”这样的方法。我不知道 dispatchEvent() 方法的所有内部检查是什么。我也不知道有什么其他方法可以使用。
    • 知道了,刚刚回答了我自己的帖子,为我的解决方案感到自豪,你确认了方法的局限性肯定有帮助,在没有显示对象时看到 FocusGained 事件的详细信息很有趣,@987654327 @然后列出 JtextFields 的详细信息,那个 reverse=null 似乎很有趣
    【解决方案2】:

    我能够通过使用decorator pattern 将我的JTextFields 包装在他们自己的侦听器中来触发我想要的方法。由于 DecoratedJTextfield 实现了 focusListener,因此可以轻松调用 focusGained() 方法。

    这里是装饰器类的一个例子:

    public class SmartTextField implements FocusListener{
    private JTextField field;
    public SmartTextField(JTextField field) {
        this.field = field;
    }
    @Override
    public void focusGained(FocusEvent e) {
        System.out.println(e);
        //Here you can add logic that applies to the field, e.g.
        field.selectAll();
        ...
    }
    @Override
    public void focusLost(FocusEvent e) {
        System.out.println(e);
        ...
    }
    public JTextField getField() {
        return field;
    }
    

    现在测试变得非常简单,您甚至可以使用空事件调用方法!但您可能需要逻辑源代码。

    @Test
    public void testSomeMethod() {
        ...
        for (SmartTextField field : SmartTextFieldCollection())
            field.focusGained(new FocusEvent(field.getField(),FocusEvent.FOCUS_GAINED));
            field.focusGained(null);
            assertTrue(condition);
            ...
    }
    

    代码奖励!对于实现,只需将修饰字段添加为焦点侦听器,它在运行和测试时都能很好地工作:

    JTextField field = new JTextField();
    SmartTextField smartTextField = new SmartTextField(field);
    field.addFocusListener(smartTextField);
    

    这特别有用,因为我现在有一个自给自足且易于测试的 textField。 中的装饰器实现了字段自己的逻辑,例如数据验证,在我的情况下准备稍后更新的信息,希望它有所帮助。它真的对我有用,为我的解决方案感到自豪。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 2013-08-02
      • 1970-01-01
      相关资源
      最近更新 更多