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