Note that there are some explanatory texts on larger screens.

plurals
  1. POJMockit and Fest UI testing
    text
    copied!<p>I have been working on a project that has numerous UI components. Since all the components are based on the MVC pattern, they are structured as a component - public interface and factory, package protected model/view/controller.</p> <p>Testing them "by hand" - using mocking tecniques is too difficult and time consuming.</p> <p>So i popped in the Fest framework - <a href="http://fest.easytesting.org/" rel="nofollow">http://fest.easytesting.org/</a>. It's simple, good and does the job.</p> <p>The problem appears when I try to use both JMockit - <a href="http://code.google.com/p/jmockit/" rel="nofollow">http://code.google.com/p/jmockit/</a> and Fest together. I noticed that Fest uses some libraries that could collide with JMockit - reflection and assert. </p> <p>When i run the test, JMockit doesn't mock the required class. I used JMockit before so I'm pretty sure it's some sort of collision between the libraries. There is no $Proxy$ generated on the mocked class, and of course, the class misbehaves.</p> <p><strong>Mocking IS required, since I have to test the full component interaction!</strong></p> <p>Versions:</p> <p>JMockit: 0.999.8</p> <p>Fest:</p> <p>Fest-swing 1.2.1 Fest-assert 1.4 Fest-util 1.1.6 Fest-reflect 1.2</p> <p>I have no intention to go conflict hunting by looking both libraries, so any help would be appretiated.</p> <p>Thanks.</p> <p><strong>UPDATE:</strong> </p> <p>The test/sample code is here:</p> <pre><code>public interface SimpleControllable { void init(); JPanel getPanel(); } public class SimpleController implements SimpleControllable { private final SimpleForm simpleForm; private final SimpleModel simpleModel; public SimpleController( final SimpleForm simpleForm, final SimpleModel simpleModel ) { this.simpleForm = simpleForm; this.simpleModel = simpleModel; } @Override public void init() { simpleForm.init(); //This works! /*simpleForm.getTestButton().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { simpleForm.getTestButton().setText(simpleModel.getSimpleValue()); } });*/ //This doesn't! simpleForm.getTestButton().setText(simpleModel.getSimpleValue()); } @Override public JPanel getPanel() { return simpleForm.getTestPanel(); } } public class SimpleModel { private final SimpleServable simpleServable; public SimpleModel(final SimpleServable simpleServable) { this.simpleServable = simpleServable; } public String getSimpleValue() { return simpleServable.getValue(); } } public interface SimpleServable { String getValue(); } public class SimpleService implements SimpleServable { private String value; @Override public String getValue() { return value; } } public class SimpleForm { private JButton testButton; private JPanel testPanel; public void init() { testPanel.setName("testPanel"); testButton.setName("testButton"); } public JButton getTestButton() { return testButton; } public JPanel getTestPanel() { return testPanel; } } public class SimpleTest extends FestSwingJUnitTestCase { @Mocked private SimpleService simpleServable; private FrameFixture window; @Override protected void onSetUp() { FailOnThreadViolationRepaintManager.install(); JFrame frameUi = GuiActionRunner.execute(new GuiQuery&lt;JFrame&gt;() { protected JFrame executeInEDT() { SimpleControllable simpleControllable = getSimpleControllable(); JFrame frame = new JFrame("TEST"); frame.add(simpleControllable.getPanel()); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.pack(); return frame; } }); robot().settings().delayBetweenEvents(1000); // IMPORTANT: note the call to 'robot()' // we must use the Robot from FestSwingTestngTestCase window = new FrameFixture(robot(), frameUi); window.show(); // shows the frameU } //Should use factory, but not neccesary for test purposes... private SimpleControllable getSimpleControllable() { SimpleForm simpleForm = new SimpleForm(); //SimpleServable simpleServable = new SimpleService(); SimpleModel simpleModel = new SimpleModel(simpleServable); SimpleControllable simpleControllable = new SimpleController( simpleForm, simpleModel ); //Initialize the component, therein lies the problem... simpleControllable.init(); return simpleControllable; } @Test public void test() throws Exception { //Before new Expectations() { { simpleServable.getValue(); result = "TEST"; } }; //When //This works! // window.panel("testPanel").button("testButton").click().requireText("TEST"); //This doesn't! window.panel("testPanel").button("testButton").requireText("TEST"); //Then } } </code></pre> <p>It seems that I blamed the framework too early. But I still don't understand the details why it doesn't work. The class <em>Service</em> IS mocked, and it should still be usable, even after delaying the expectations. I understand the time problem(initialization of the component), but have no idea how to "fix" this.</p> <p>Thanks.</p> <p><strong>UPDATE2:</strong></p> <p>Thanks, Rogerio. You can test the component with FEST, but it doesn't really take advantage of JMockit, and there are classes that have quite a lot of methods(yes, I know - SRP, but let's try stay on this path) and would benefit greatly from a mocking framework such as JMockit. I used this before posting the question here, so you can use it yourself, and understand that this is not the way I want to go:</p> <pre><code>public class SimpleTest extends FestSwingJUnitTestCase { //This works, and I used this mechanism before, but this is without the help of JMockit. //If you have a lot of methods you want to mock this test turns into chaos. public static class MockSimpleServable implements SimpleServable{ @Override public String getValue() { return "TEST"; } } // @Mocked // private SimpleServable simpleServable; private FrameFixture window; @Override protected void onSetUp() { FailOnThreadViolationRepaintManager.install(); JFrame frameUi = GuiActionRunner.execute(new GuiQuery&lt;JFrame&gt;() { protected JFrame executeInEDT() { SimpleControllable simpleControllable = getSimpleControllable(); JFrame frame = new JFrame("TEST"); frame.add(simpleControllable.getPanel()); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.pack(); return frame; } }); robot().settings().delayBetweenEvents(1000); // IMPORTANT: note the call to 'robot()' // we must use the Robot from FestSwingTestngTestCase window = new FrameFixture(robot(), frameUi); window.show(); // shows the frameU } //Should use factory, but not neccesary for test purposes... private SimpleControllable getSimpleControllable() { SimpleForm simpleForm = new SimpleForm(); //SimpleServable simpleServable = new SimpleService(); SimpleServable simpleServable = new MockSimpleServable(); SimpleModel simpleModel = new SimpleModel(simpleServable); SimpleControllable simpleControllable = new SimpleController( simpleForm, simpleModel ); //Initialize the component, therein lies the problem... simpleControllable.init(); return simpleControllable; } @Test public void test() throws Exception { //This works! // window.panel("testPanel").button("testButton").click().requireText("TEST"); //This doesn't! window.panel("testPanel").button("testButton").requireText("TEST"); } } </code></pre> <p><strong>The question remains - does anybody know some way I could test this with JMockit, don't forget the EDT violation.</strong></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload