I have a little problem with my unit tests for a Swing application. What I want to do is pass a paintable object to my JPanel and everytime I do that it should repaint itself.
So much for the basic scenario, now on to my unit tests:
public class GraphicViewImplTest {
private JFrame frame;
private GraphicViewImpl view; //This is my JPanel
private GraphicLineSpy firstGraphicLine;
private Line firstLine;
@Before
public void setUp() throws Exception {
frame = new JFrame();
view = new GraphicViewImpl();
frame.add(view);
frame.setVisible(true);
firstLine = new Line();
firstLine.setStart(new Point(11, 12));
firstLine.setEnd(new Point(21, 22));
firstGraphicLine = new GraphicLineSpy(firstLine);
}
@Test
public void whenReceivingLine_shouldPaintLine() {
view.receiveShape(firstGraphicLine);
assertTrue(firstGraphicLine.wasPainted());
}
}
As you can see I'm passing GraphicLineSpy to my view. The GraphicLine class is basically a decorator for the Line class that knows how to paint a line in Swing. The GraphicLineSpy overrides the paint method of the GraphicLine and just sets a flag to true, so I can check if the paint method was called.
Now on to the implemenation of my GraphicView JPanel:
public class GraphicViewImpl extends JPanel implements GraphicView, Observer {
protected GraphicViewPresenter presenter;
protected List<GraphicShape> graphicShapeList = new LinkedList<>();
@Override
public void receiveShape(GraphicShape graphicShape) {
graphicShapeList.add(graphicShape);
graphicShape.addObserver(this);
repaint();
}
@Override
public void removeShape(GraphicShape graphicShape) {
graphicShapeList.remove(graphicShape);
graphicShape.removeObserver(this);
repaint();
}
public void setPresenter(GraphicViewPresenter presenter) {
this.presenter = presenter;
}
@Override
public void update() {
repaint();
}
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
for (GraphicShape graphicShape : graphicShapeList)
graphicShape.paint(graphics);
}
}
Now, my problem is that when I run these tests they say that my GraphicLine was not painted. However, when I actually run the program and add a new GraphicLine it works perfectly fine, all my Shapes get painted. Am I missing something in the test setup?
Moreover, and this is probably the most important part, I guess it's not really an optimal solution to start up a whole JFrame everytime I run my tests, so I was wondering how I would best go about creating a test double that doesn't break the whole repaint functionality.
Thanks in advance for any hints!
I think you should concentrate on testing your code instead of the JPanel implementation, therefore you should mock out these other dependencies using the Mockito framework (or any other):
public class GraphicViewImplTest {
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock
private Graphics2D graphics; // not tested dependency
@Mock
private GraphicShape firstLine; // not tested dependency
private GraphicViewImpl view; //This is my JPanel
@Before
public void setUp() throws Exception {
view = spy(new GraphicViewImpl());
doNothing().when(view).repaint();
}
@Test
public void whenReceivingLine_shouldPaintLine() {
view.receiveShape(firstGraphicLine);
verify(view).repaint();
verify(firstLine,never()).paint(graphics);
view.paintComponent(graphics);
verify(firstLine).paint(graphics);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.