AvdPav
AvdPav

Reputation: 190

I can not test the Swing GUI with AssertJ

I can not test the GUI in my application using the AssertJ library. So as not to spread all the code of your program, wrote a test program to show the essence of the problem.

package AssertJ;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SomeFrame extends JFrame {
    JFrame frame;
    JLabel label1;
    JButton button1;

    public SomeFrame() {
        createGUI();

    }

    public void createGUI() {
        frame = new JFrame("EspiaServer");
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        label1 = new JLabel("Random");
        button1 = new JButton("Click Me!");
        button1.setName("button");
        button1.setSize(200, 200);
        button1.addActionListener(listener);
        frame.add(label1);
        frame.add(button1);
        frame.pack();


    }

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


    ActionListener listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            int i = (int) (Math.random() * 99999) + 0;
            label1.setText(String.valueOf(i));
        }
    };
}

Here's the test for it:

package AssertJ;

import org.assertj.swing.edt.GuiActionRunner;
import org.assertj.swing.fixture.FrameFixture;
import org.junit.Before;
import org.junit.Test;


public class SomeFrameTest {
    private FrameFixture window;

    @Before
    public void setUp() {
        SomeFrame frame = GuiActionRunner.execute(() -> new SomeFrame());
        window = new FrameFixture(frame);
        window.show(); // shows the frame to test
    }


    @Test
    public void createGUI() {
        window.button("button").click();
    }
}

So that's it. The essence of the application. In the frame, there is one button, when pressed, Jlabel changes its value to a random number. The application starts, everything is fine. But when I run the test. He creates the gui of this application and another window in the upper left corner that constantly flashes and twitches. Accordingly, the command window.button ("button").click(); is not satisfied. enter image description here

After a few seconds, the app throws the exception :

rg.assertj.swing.exception.ComponentLookupException: Unable to find component using matcher org.assertj.swing.core.NameMatcher[name='button', type=javax.swing.JButton, requireShowing=true].

Component hierarchy:
AssertJ.SomeFrame[name='frame0', title='', enabled=true, visible=true, showing=true]
  javax.swing.JRootPane[]
    javax.swing.JPanel[name='null.glassPane']
    javax.swing.JLayeredPane[]
      javax.swing.JPanel[name='null.contentPane']


    at org.assertj.swing.core.BasicComponentFinder.componentNotFound(BasicComponentFinder.java:287)
    at org.assertj.swing.core.BasicComponentFinder.find(BasicComponentFinder.java:272)
    at org.assertj.swing.core.BasicComponentFinder.find(BasicComponentFinder.java:265)
    at org.assertj.swing.core.BasicComponentFinder.findByName(BasicComponentFinder.java:200)
    at org.assertj.swing.fixture.AbstractContainerFixture.findByName(AbstractContainerFixture.java:641)
    at org.assertj.swing.fixture.AbstractContainerFixture.button(AbstractContainerFixture.java:143)
    at AssertJ.SomeFrameTest.createGUI(SomeFrameTest.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Upvotes: 0

Views: 1342

Answers (2)

pamal Sahan
pamal Sahan

Reputation: 481

write window.maximize() after the window.show() it works for me.

Upvotes: 2

Thomas Kläger
Thomas Kläger

Reputation: 21435

Your problem is that you have two JFrames:

  • SomeFrame is a JFrame (SomeFrame extends JFrame)
  • SomeFrame contains a JFrame (JFrame frame;)

The way your test code is structured it expects the button("button") to be contained within the SomeFrame JFrame object, but you add it to the frame JFrame object.

You can fix this problem by getting rid of the JFrame frame instance variable:

public class SomeFrame extends JFrame {
    JLabel label1;
    JButton button1;

    public SomeFrame() {
        super("EspiaServer");
        createGUI();

    }

    public void createGUI() {
        setLayout(new FlowLayout());
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
        label1 = new JLabel("Random");
        button1 = new JButton("Click Me!");
        button1.setName("button");
        button1.setSize(200, 200);
        button1.addActionListener(listener);
        add(label1);
        add(button1);
        pack();
    }
    // some code left out
}

Upvotes: 1

Related Questions