如何为单元测试触发 Swing GUI 事件

How to fire Swing GUI events for Unit Testing

我正在使用 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' 的 FocusEvents?考虑到这是用于 junit 测试,没有 GUI 的选项会很棒。

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

I've read that it might be because there's no display.

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

an option without GUI would be awesome.

您或许可以使用:

field.dispatchEvent(...);

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

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

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

这里是装饰器的例子class,:

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。 装饰器实现了字段自己的逻辑,比如数据验证,在我的例子中准备了稍后更新的信息,希望它有所帮助。它真的对我有用,为我的解决方案感到自豪。