目前我正在研究 TextField 和默认/取消按钮的问题。在使用 TestFX 测试假定的修复程序时,我遇到了事件调度 (?) 的差异,这会导致测试失败,而应用程序似乎正在运行。
下面是一个非常简化的版本:
- 只是一个简单的 ui,由一个框内的 textField 组成,用于 Application/Test
- textField 有一个 (key-) 处理程序,当按下a时会触发 actionEvent
- textField 有一个使用 actionEvent 的操作处理程序
- (key-) 处理程序检查操作是否已被使用(这里:简单日志,在实际上下文中,如果操作被使用,则必须使用 (key-) 事件)
修复的关键部分是使用 textField 作为源和目标创建 actionEvent(以防止在调度期间将事件复制到新实例中):
ActionEvent action = new ActionEvent(field, field);
运行应用程序时,这似乎足以使其工作。运行测试时,失败 - 事件被复制到另一个实例,因此被消耗的事件与在调度中传递的事件是不同的实例(只能在调试期间看到)。无法确定发生这种情况的确切地点/原因。
问题是:这种差异是预期的,如果是,为什么/在哪里?或者我做错了什么(远非零概率)?
重现
- 运行应用程序,按 a:注意说明已触发的 actionEvent 已被消耗的日志
- 运行测试,注意日志说明触发的 actionEvent 没有被消耗
编码:
public class ActionApp extends Application {
// create a simple ui - static because must be same for ActionTest
public static Parent createContent() {
TextField field = new TextField();
// some handler to fire an actionEvent
field.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.A) {
ActionEvent action = new ActionEvent(field, field);
field.fireEvent(action);
LOG.info("action/consumed? " + action + action.isConsumed());
}
});
// another handler to consume the fired action
field.addEventHandler(ActionEvent.ACTION, e -> {
e.consume();
LOG.info("action received " + e + e.isConsumed());
});
VBox actionUI = new VBox(field);
return actionUI;
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setTitle(FXUtils.version());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(ActionApp.class.getName());
}
考试:
public class ActionTest extends ApplicationTest {
/**
* Does not really test anything, just to see the output.
*/
@Test
public void testConsumeA() {
// sanity: focused to receive the key
verifyThat(".text-field", NodeMatchers.isFocused());
press(KeyCode.A);
}
@Override
public void start(Stage stage) {
Parent root = ActionApp.createContent();
Scene scene = new Scene(root, 100, 100);
stage.setScene(scene);
stage.show();
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(ActionTest.class.getName());
}
我的环境是 2018 年 10 月在 win10 上的 fx11 和 TestFX。仅供参考:在 testFX 中打开了一个问题