简体   繁体   English

如何创建支持重绘功能的JFrame / JPanel的模拟

[英]How do I create a Mock of a JFrame/JPanel that supports repaint functionality

I have a little problem with my unit tests for a Swing application. 我的Swing应用程序的单元测试有点问题。 What I want to do is pass a paintable object to my JPanel and everytime I do that it should repaint itself. 我想要做的是将一个可绘制的对象传递给我的JPanel,每次我这样做都应该重新绘制自己。

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. 正如您所看到的,我正在将GraphicLineSpy传递给我。 The GraphicLine class is basically a decorator for the Line class that knows how to paint a line in Swing. GraphicLine类基本上是Line类的装饰器,它知道如何在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. GraphicLineSpy会覆盖GraphicLine的paint方法,只需将标志设置为true,这样我就可以检查是否调用了paint方法。

Now on to the implemenation of my GraphicView JPanel: 现在开始实现我的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. 现在,我的问题是,当我运行这些测试时,他们说我的GraphicLine没有画。 However, when I actually run the program and add a new GraphicLine it works perfectly fine, all my Shapes get painted. 但是,当我实际运行程序并添加一个新的GraphicLine时,它的工作完全正常,我的所有Shapes都会被绘制。 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. 而且,这可能是最重要的部分,我想这并不是每次运行我的测试时启动整个JFrame的最佳解决方案,所以我想知道如何最好地创建一个不会破坏的测试双整个重绘功能。

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): 我想你应该专注于测试,而不是执行的JPanel 你的代码,因此,你应该模拟出使用框架的Mockito(或任何其它)这些依赖关系:

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);
    }
}

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

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