简体   繁体   English

为什么JPanelFixture.comboBox()。pressAndReleaseKeys()与FEST一起使用,但不与AssertJ一起使用?

[英]Why does JPanelFixture.comboBox().pressAndReleaseKeys() work with FEST, but not with AssertJ?

When trying to simulate input using AssertJ's pressAndReleaseKeys() for unit testing a JComboBox in a Java Swing program, I am not seeing the expected behavior. 当尝试使用AssertJ的pressAndReleaseKeys()模拟输入以在Java Swing程序中对JComboBox进行单元测试时,我没有看到预期的行为。 The program will most often hang on the pressAndReleaseKeys line and then fail, or occasionally will delete all the text currently in the JComboBox being tested, causing later assertions to fail (ie requireSelection()). 该程序通常会挂在pressAndReleaseKeys行上,然后失败,或偶尔会删除当前正在测试的JComboBox中的所有文本,导致以后的断言失败(即requireSelection())。 The stack trace I receive for the provided example program (see below) when it hangs is as follows: 我挂起的提供的示例程序(见下文)我收到的堆栈跟踪如下:

Focus change to javax.swing.JComboBox[name='combob', selectedItem='Bean', contents=["Pork", "Beans", "Rice"], editable=true, enabled=true, visible=true, showing=true] failed focus owner: javax.swing.plaf.metal.MetalComboBoxEditor$1(javax.swing.JTextField)[name=null, text='Bean', enabled=true, visible=true, showing=true] 重点更改为javax.swing.JComboBox [name ='combob',selectedItem ='Bean',contents = [“Pork”,“Beans”,“Rice”],editable = true,enabled = true,visible = true,显示= true]焦点所有者失败:javax.swing.plaf.metal.MetalComboBoxEditor $ 1(javax.swing.JTextField)[name = null,text ='Bean',enabled = true,visible = true,shows = true]

org.assertj.swing.exception.ActionFailedException org.assertj.swing.exception.ActionFailedException
at org.assertj.swing.exception.ActionFailedException.actionFailure(ActionFailedException.java:33) at org.assertj.swing.exception.ActionFailedException.actionFailure(ActionFailedException.java:33)
at org.assertj.swing.core.BasicRobot.focus(BasicRobot.java:301) 在org.assertj.swing.core.BasicRobot.focus(BasicRobot.java:301)
at org.assertj.swing.core.BasicRobot.focusAndWaitForFocusGain(BasicRobot.java:270) 在org.assertj.swing.core.BasicRobot.focusAndWaitForFocusGain(BasicRobot.java:270)
at org.assertj.swing.driver.ComponentDriver.focusAndWaitForFocusGain(ComponentDriver.java:419) 在org.assertj.swing.driver.ComponentDriver.focusAndWaitForFocusGain(ComponentDriver.java:419)
at org.assertj.swing.driver.ComponentDriver.pressAndReleaseKeys(ComponentDriver.java:315) 在org.assertj.swing.driver.ComponentDriver.pressAndReleaseKeys(ComponentDriver.java:315)
at org.assertj.swing.fixture.AbstractComponentFixture.pressAndReleaseKeys(AbstractComponentFixture.java:293) at org.assertj.swing.fixture.AbstractComponentFixture.pressAndReleaseKeys(AbstractComponentFixture.java:293)
at javapractice.ComboBoxSampleTest.testMain(ComboBoxSampleTest.java:59) 在javapractice.ComboBoxSampleTest.testMain(ComboBoxSampleTest.java:59)

I have been using FEST and am hoping to migrate my tests to AssertJ since it is being actively maintained, whereas FEST hasn't been updated for years. 我一直在使用FEST,我希望将我的测试迁移到AssertJ,因为它正在积极维护,而FEST多年来一直没有更新。 I used Joel Costigliola's migration from Fest to AssertJ guide, but am having trouble when simulating keyboard input by using pressAndReleaseKeys(). 我使用了Joel Costigliola 从Fest到AssertJ指南的迁移 ,但是在使用pressAndReleaseKeys()模拟键盘输入时遇到了麻烦。 I am able to simulate input when using a JTextComponentFixture ie 我可以在使用JTextComponentFixture时模拟输入,即

window.textBox("textB").pressAndReleaseKeys(KeyEvent.VK_LEFT);

(where window is a FrameFixture, a container in both AssertJ and FEST), but I am unable to simulate input when using a JComboBoxFixture ie (其中window是FrameFixture,AssertJ和FEST中的容器),但是当使用JComboBoxFixture时我无法模拟输入,即

window.comboBox("comboB").pressAndReleaseKeys(KeyEvent.VK_LEFT);

This obstacle can usually be avoided, since most "key presses" can be simulated by using enterText ie 通常可以避免这种障碍,因为大多数“按键”可以通过使用enterText来模拟

window.comboBox("comboB").enterText("\n"); //to press the enter key
window.comboBox("comboB").enterText("\b"); //to press the backspace key

but I would like to be able to use the arrow keys, control key, and other keys where I can't simulate the key press using enterText(). 但我希望能够使用箭头键,控制键和其他键,我无法使用enterText()模拟按键。 Is this failure due to an issue with my environment*, an issue with the way I'm using it, or is the API itself flawed? 这种失败是由于我的环境问题*,我使用它的方式的问题,还是API本身存在缺陷?

I tried using pressKey() and then releaseKey() as a workaround, but that doesn't work with JComboBox either, and my program instead hangs on pressKey(). 我尝试使用pressKey()然后使用releaseKey()作为一种解决方法,但这也不适用于JComboBox,而我的程序则挂起在pressKey()上。 That being said, I am not able to use pressKey() and releaseKey() to test a JComboBox with FEST either. 话虽这么说,我无法使用pressKey()和releaseKey()来测试带有FEST的JComboBox。

*Environment details: *环境细节:
Language version: java version "1.8.0_131" 语言版本:java版“1.8.0_131”
Platform version (eg .NET 3.5; note that this isn't always implicit from the language version, or vice versa) 平台版本(例如.NET 3.5;请注意,这并非始终隐含在语言版本中,反之亦然)
Operating system: Red Hat Release 6.10 (Santiago) 操作系统:Red Hat版本6.10(圣地亚哥)
IDE: Netbeans 8.0.2 IDE:Netbeans 8.0.2

Sample GUI application: 示例GUI应用程序:

package javapractice;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class ComboBoxSample extends JFrame implements ItemListener{
    JPanel jp;
    JComboBox jcb;
    JLabel result;
    JLabel title;
    JTextField jtc;

    public static void main(String[] args) {
        ComboBoxSample frame = new ComboBoxSample();
    }

    ComboBoxSample() {
        super();
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setTitle("Testing AssertJ");
        this.setLayout(new FlowLayout());
        jp = new JPanel();
        jcb = new JComboBox(new String[] {"Pork", "Beans", "Rice"});
        jcb.setEditable(true);
        jcb.setName("combob");
        jtc = new JTextField();
        jtc.setEditable(true);
        jtc.setPreferredSize(new Dimension(150, 25));
        jtc.setName("textb");
        title = new JLabel("Food: ");
        result = new JLabel("No food");
        jp.add(title);
        jp.add(jcb);
        jp.add(result);
        jp.add(jtc);
        this.add(jp);
        this.setLocationRelativeTo(null);
        jcb.addItemListener(this);


        this.pack();
        this.repaint();        
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        if(e.getSource() == jcb) {
            result.setText("I'm eating " + jcb.getSelectedItem());
        }
        this.pack();
    }

    public void cleanUp() {
        jcb = null;
        result = null;
        jtc = null;
        jp = null;
        title = null;
    }   
}

Test File for Fest: Fest的测试文件:

package javapractice;

import com.sun.glass.events.KeyEvent;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * Fest imports.
 */
import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
import org.fest.swing.edt.GuiActionRunner;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.fixture.FrameFixture;

public class ComboBoxSampleTest {
    private FrameFixture window;
    private ComboBoxSample frame;

    @BeforeClass
    public static void setUpClass() {
        FailOnThreadViolationRepaintManager.install();
    }

    @AfterClass
    public static void tearDownClass() {

    }

    @Before
    public void setUp() {
        frame = GuiActionRunner.execute(new GuiQuery<ComboBoxSample>() {
            @Override
            protected ComboBoxSample executeInEDT() {
                return new ComboBoxSample();
            }
        });
        window = new FrameFixture(frame);
        window.show();
    }

    @After
    public void tearDown() {
        window.cleanUp();
        frame.cleanUp();
    }

    /**
     * Test of main method, of class ComboBoxSample.
     */
    @Test
    public void testMain() {
        //Delay so that we can see what's going on
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ie) {

        }

        window.textBox("textb").enterText("hi there");
        window.textBox("textb").pressAndReleaseKeys(KeyEvent.VK_BACKSPACE);
        window.comboBox().replaceText("Bean");
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_S);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_ENTER);
    }
}

Test File for AssertJ: AssertJ的测试文件:

package javapractice;

import com.sun.glass.events.KeyEvent;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * AssertJ imports.
 */
import org.assertj.swing.edt.FailOnThreadViolationRepaintManager;
import org.assertj.swing.edt.GuiActionRunner;
import org.assertj.swing.fixture.FrameFixture;

public class ComboBoxSampleTest {
    private FrameFixture window;
    private ComboBoxSample frame;

    @BeforeClass
    public static void setUpClass() {
        FailOnThreadViolationRepaintManager.install();
    }

    @AfterClass
    public static void tearDownClass() {

    }

    @Before
    public void setUp() {
        frame = GuiActionRunner.execute(() -> new ComboBoxSample());
        window = new FrameFixture(frame);
        window.show();
    }

    @After
    public void tearDown() {
        window.cleanUp();
        frame.cleanUp();
    }

    /**
     * Test of main method, of class ComboBoxSample.
     */
    @Test
    public void testMain() {
        //Delay so that we can see what's going on
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ie) {

        }

        window.textBox("textb").enterText("hi there");
        window.textBox("textb").pressAndReleaseKeys(KeyEvent.VK_BACKSPACE);
        window.comboBox().replaceText("Bean");
        //the above line is the last one to execute
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_S);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_DOWN);
        window.comboBox().pressAndReleaseKeys(KeyEvent.VK_ENTER);
    }
}

This is not an answer to the question, but a workaround that allows the desired behavior. 这不是问题的答案,而是允许所需行为的解决方法。 This issue can be mitigated by invoking robot() for the comboBox(). 可以通过为comboBox()调用robot()来缓解此问题。

Instead of 代替

window.comboBox().pressAndReleaseKeys(KeyEvent.VK_S);

try doing 试着做

window.comboBox().robot().pressAndReleaseKeys(KeyEvent.VK_S);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM