禁用的Swing组件的点击问题

6

我有一个禁用的JTable,它提供了一个弹出菜单:

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTable;

public class DisabledTableFrame extends JFrame {

    public DisabledTableFrame() {

        setSize(200, 100);
        setTitle(getClass().getCanonicalName());
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        JTable table = new JTable();
        add(table);

        table.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                mouseReleased(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                new PopupMenu();
            }

        });

        table.setEnabled(false);
        setVisible(true);
    }

    public static void main(String[] args) {
        new DisabledTableFrame();

    }

    private class PopupMenu extends JPopupMenu {

        public PopupMenu() {

            JMenuItem menuItem = new JMenuItem("TEST");
            add(menuItem);
            setVisible(true);
        }
    }
}

因此,在使用AssertJ Swing测试此功能时:

import org.assertj.swing.edt.GuiActionRunner;
import org.assertj.swing.edt.GuiQuery;
import org.assertj.swing.fixture.FrameFixture;
import org.assertj.swing.junit.testcase.AssertJSwingJUnitTestCase;
import org.junit.Test;

public class PopupTestCase extends AssertJSwingJUnitTestCase {

    protected FrameFixture window;

    @Override
    protected void onSetUp() {
        DisabledTableFrame mainFrame = GuiActionRunner
                .execute(new GuiQuery<DisabledTableFrame>() {
                    protected DisabledTableFrame executeInEDT() {

                        return new DisabledTableFrame();
                    }
                });

        window = new FrameFixture(robot(), mainFrame);
    }

    @Test
    public void popupShouldBeOpened() {

        window.table().showPopupMenu();
    }
}

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>AssertJSwingInactiveTest</groupId>
    <artifactId>AssertJSwingInactiveTest</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-swing-junit-4.5</artifactId>
            <version>1.2.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

当表格启用时,它能正常工作。但当测试禁用表格的popupShoudBeOpened()函数时,会抛出以下异常:
   java.lang.IllegalStateException: Expecting component javax.swing.JTable[name=null, rowCount=0, columnCount=0, enabled=false, visible=true, showing=true] to be enabled
at org.assertj.swing.driver.ComponentPreconditions.checkEnabled(ComponentPreconditions.java:68)
at org.assertj.swing.driver.ComponentPreconditions.checkEnabledAndShowing(ComponentPreconditions.java:48)
at org.assertj.swing.driver.ComponentDriver$2.executeInEDT(ComponentDriver.java:555)
at org.assertj.swing.edt.GuiTask.run(GuiTask.java:38)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:745)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:706)
at java.awt.EventQueue$3.run(EventQueue.java:704)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:715)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
at org.assertj.swing.edt.GuiActionRunner.execute(GuiActionRunner.java:103)
at org.assertj.swing.driver.ComponentDriver.checkInEdtEnabledAndShowing(ComponentDriver.java:552)
at org.assertj.swing.driver.ComponentDriver.invokePopupMenu(ComponentDriver.java:519)
at org.assertj.swing.fixture.AbstractJPopupMenuInvokerFixture.showPopupMenu(AbstractJPopupMenuInvokerFixture.java:95)
at GUITestCase.popupShouldBeOpened(GUITestCase.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

由于弹出菜单明显在禁用表格上起作用,我该如何让AssertJ“右键单击”禁用表格?


请问您可以发布您的代码吗? - bircastri
是 AssertJ 抛出了异常,因为它期望表格已启用。请提供完整的异常跟踪。 - Leet-Falcon
@bircastri,我将问题简化到了基础,并提供了整个堆栈跟踪。很高兴看到仍然有人使用AssertJ Swing。 - Angelo Berlin
1个回答

1

AsserJ期望被测试的组件是启用的。
一旦它被禁用,它就会抛出IllegalStateException异常。
请查看AbstractComponentFixture API 这里

解决此问题的一种方法是将其分为2个测试,并在预计表格被禁用时包含异常:

@Test
public void popupShouldBeOpenedIfTableIsDisabled() {
    try {
        window.table().showPopupMenu();
    } catch (IllegalStateException e) {
        // Continue normally if IllegalStateException was thrown since the table is disabled on purpose.
    }
}

@Test
public void popupShouldBeOpenedIfTableIsEnabled() {
    window.table().showPopupMenu();
    // IllegalStateException will fail the test since the table is enabled.
}

感谢您处理我的问题。问题是,弹出菜单无论如何都不会打开。但我需要打开它才能点击菜单项。有没有办法禁用AssertJ的前置条件检查? - Angelo Berlin
不客气。问题在于驱动程序组件将始终检查EDT +启用+显示。除非您更改源代码,否则必须满足这3个先决条件才能进行测试。 - Leet-Falcon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接