我完全陷入了java测试中;这是关于通过测试方法将字符'a‘发送给JTextField的JFrame组件。
JFrame类实现KeyListener接口,因此重写KeyPressed、KeyTyped和KeyReleased。同时,我将JTextField的所有按键传递给JFrame;在JFrame构造函数中,我有:
JTextField txf_version = new JTextField();
txf_version.addKeyListener(this);我想测试这个行为,然后在JTextField中模拟一个字符的动作。
所有的尝试都失败了;我尝试了java.awt.Robot类,比如:看看堆栈溢出中的另一篇文章,但是我得到了一个奇怪的行为:调用
robot.keyPress(KeyEvent.VK_A);直接在IDE中显示字符,而不是在虚拟JFrame中显示!尝试使用requestFocus()或requestFocusInWindow()是无效的。
我还尝试过使用KeyEvents:
KeyEvent key = new KeyEvent(bookWindow.txf_version, KeyEvent.KEY_PRESSED, System
.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'a');
bookWindow.txf_version.dispatchEvent(key);但是textfield的text属性也没有被更改.
下面是我现在的方法:
@Test
void testBtnSaveChangesBecomesRedWhenVersionChanged() throws AWTException,
InterruptedException, NoSuchFieldException, IllegalAccessException {
initTest();
KeyEvent key = new KeyEvent(bookWindow.txf_version, KeyEvent.KEY_PRESSED, System
.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'a');
bookWindow.txf_version.dispatchEvent(key);
System.out.println("dans txf_version : " + bookWindow.txf_version.getText
());
assertEquals(Color.RED, bookWindow.getBtnSaveChangesForegroundColor());
}我可以通过在JFrame的子类中编写main()方法来查看实际行为,但我认为了解如何模拟swing组件测试的键是有用的。
谢谢
编辑:我根据AJNeufeld的答案更改了测试代码,但仍然无法工作。这是我的测试代码:
@Test
void testBtnSaveChangesBecomesRedWhenVersionChanged() throws AWTException,
InterruptedException, NoSuchFieldException, IllegalAccessException,
InvocationTargetException {
//bookEditor2 & bookWindow
SwingUtilities.invokeAndWait(() -> {
bookWindow = new BookWindow();
VectorPerso two = new VectorPerso();
two.add(le_livre_de_la_jungle);
two.add(elogeMaths);
bookWindow.setTableDatas(two);
bookWindow.table.setRowSelectionInterval(1, 1);
bookWindow.txf_version.requestFocusInWindow();
KeyEvent key = new KeyEvent(bookWindow.txf_version, KeyEvent.KEY_TYPED, System
.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'a');
bookWindow.txf_version.dispatchEvent(key);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("dans txf_version : " + bookWindow.txf_version.getText
());
assertEquals(Color.RED, bookWindow.getBtnSaveChangesForegroundColor());
});
}plintln行在控制台中生成一个文本:"dans txf_version : 0",这表示键没有发送到txf_version。
编辑2:
新尝试:
@Test
void testBtnSaveChangesBecomesRedWhenVersionChanged() throws AWTException,
InterruptedException, NoSuchFieldException, IllegalAccessException,
InvocationTargetException {
//bookEditor2 & bookWindow
SwingUtilities.invokeAndWait(() -> {
bookWindow = new BookWindow();
VectorPerso two = new VectorPerso();
two.add(le_livre_de_la_jungle);
two.add(elogeMaths);
bookWindow.setTableDatas(two);
bookWindow.table.setRowSelectionInterval(1, 1);
bookWindow.txf_version.requestFocusInWindow();
KeyEvent key = new KeyEvent(bookWindow.txf_version, KeyEvent.KEY_TYPED, System
.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'a');
bookWindow.txf_version.dispatchEvent(key);
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
SwingUtilities.invokeAndWait(() -> {
System.out.println("dans txf_version : " + bookWindow.txf_version.getText
());
assertEquals(Color.RED, bookWindow.getBtnSaveChangesForegroundColor());
});
}发布于 2017-11-17 02:07:14
我认为你做错了几件事,但如果没有一个完整的例子,就很难说了。
首先,JTextField并不真正关心KEY_PRESSED事件。它与KEY_TYPED事件有关。
其次,Swing处理事件分派线程(EDT)上的事件,这不一定是JUnit将要运行的线程。当你不在美国东部时间的时候,你真的不应该改变事情。我不确定eventDispatch()是否会切换到EDT。有可能。但是它也可能使用invokeLater()执行,在这种情况下,执行会立即传递给assertEquals(),这会失败,因为事件处理还没有发生。
下面是一个最小的、完整的、可验证的示例,它显示了发送的键(它改变了按钮的颜色)和一个检查它并通过的JUnit测试用例:
首先,正在测试的代码:
public class SwingUnitTesting extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(SwingUnitTesting::new);
}
JTextField tf = new JTextField();
JButton btn = new JButton("Test Button");
SwingUnitTesting() {
add(tf, BorderLayout.PAGE_END);
add(btn, BorderLayout.PAGE_START);
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
btn.setForeground(Color.RED);
}
});
setSize(200, 80);
setLocationByPlatform(true);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
}
}单元测试:
public class SwingUnitTestingTest {
SwingUnitTesting sut;
@Before
public void setUp() throws Exception {
SwingUtilities.invokeAndWait(() -> {
sut = new SwingUnitTesting();
});
}
@Test
public void btnNotRedBeforeKeypress() throws InvocationTargetException, InterruptedException {
SwingUtilities.invokeAndWait(() -> {
assertNotEquals(Color.RED, sut.btn.getForeground());
});
}
@Test
public void btnRedAfterKeypress() throws InvocationTargetException, InterruptedException {
SwingUtilities.invokeAndWait(() -> {
sut.tf.requestFocusInWindow();
sut.tf.dispatchEvent(new KeyEvent(sut.tf,
KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0,
KeyEvent.VK_UNDEFINED, 'A'));
assertEquals(Color.RED, sut.btn.getForeground());
});
}
}在运行swing测试时,您可能可以使用一些JUnit @Rule技巧或自定义运行程序来自动更改为EDT。
更新
我很好奇,并试图找到一个现有的@Rule,它将@Before、@Test和@After代码放在EDT上,但我的Google失败了;我知道我以前见过它,但我找不到它。最后,我创造了我自己的:
public class EDTRule implements TestRule {
@Override
public Statement apply(Statement stmt, Description dscr) {
return new Statement() {
private Throwable ex;
@Override
public void evaluate() throws Throwable {
SwingUtilities.invokeAndWait(() -> {
try {
stmt.evaluate();
} catch (Throwable t) {
ex = t;
}
});
if (ex != null) {
throw ex;
}
}
};
}
}使用这个规则,JUnit测试变得更简单了:
public class SwingUnitTestingTest {
@Rule
public TestRule edt = new EDTRule();
SwingUnitTesting sut;
@Before
public void setUp() throws Exception {
sut = new SwingUnitTesting();
}
@Test
public void btnNotRedBeforeKeypress() {
assertNotEquals(Color.RED, sut.btn.getForeground());
}
@Test
public void btnRedAfterKeypress() {
sut.tf.requestFocusInWindow();
sut.tf.dispatchEvent(
new KeyEvent(sut.tf, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'A'));
assertEquals(Color.RED, sut.btn.getForeground());
}
}在MacOS上使用jdk1.8.0_121进行测试
发布于 2017-11-16 21:23:30
哟,我猜你有两个选择
( 1)仍然需要使用SWING找到解决方案(但在这种情况下,我没有经验,也没有任何想法来帮助您)。
2)使用Sikulli java框架对桌面应用程序进行测试。然后可以添加依赖性
运行后,您将看到,您的光标是移动按钮,并点击它。
有关更多细节,请在web中找到关于Sikulli + Java的示例。
发布于 2019-03-01 18:46:54
最近,我不得不测试一个定制的KeyAdapter,并创建了一个定制的JTextField来分派关键事件。我使用的一段代码如下:
public class ProcessKeyOnTextFieldTest {
@Test
public void pressKeyTest() throws Exception {
JTextFieldWithTypedKeySupport textField = new JTextFieldWithTypedKeySupport();
textField.pressKey('a');
textField.pressKey('b');
assertEquals("ab", textField.getText());
}
class JTextFieldWithTypedKeySupport extends JTextField {
int timestamp;
void pressKey(char key) throws InvocationTargetException, InterruptedException {
SwingUtilities.invokeAndWait(() -> super.processKeyEvent(createEvent(key)));
}
KeyEvent createEvent(char keyChar) {
return new KeyEvent(this, KeyEvent.KEY_TYPED, timestamp++, 0, KeyEvent.VK_UNDEFINED, keyChar);
}
}
}https://stackoverflow.com/questions/47336703
复制相似问题