【问题标题】:How do I create a Mock of a JFrame/JPanel that supports repaint functionality如何创建支持重绘功能的 JFrame/JPanel 模拟
【发布时间】:2016-12-10 16:43:28
【问题描述】:

我对 Swing 应用程序的单元测试有一点问题。 我想要做的是将一个可绘制对象传递给我的 JPanel,并且每次我这样做时它都应该重新绘制自己。

关于基本场景,现在开始我的单元测试:

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

}

如您所见,我正在将 GraphicLineSpy 传递给我的视图。 GraphicLine 类基本上是 Line 类的装饰器,它知道如何在 Swing 中绘制线条。 GraphicLineSpy 覆盖了 GraphicLine 的 paint 方法,只是将一个标志设置为 true,因此我可以检查是否调用了 paint 方法。

现在开始我的 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);
    }
}

现在,我的问题是,当我运行这些测试时,他们说我的 GraphicLine 没有绘制。但是,当我实际运行程序并添加一个新的 GraphicLine 时,它​​工作得非常好,我所有的形状都被绘制了。我在测试设置中遗漏了什么吗?

此外,这可能是最重要的部分,我想这并不是每次运行测试时启动整个 JFrame 的最佳解决方案,所以我想知道如何最好地创建一个不不要破坏整个重绘功能。

提前感谢您的任何提示!

【问题讨论】:

    标签: java swing unit-testing tdd


    【解决方案1】:

    我认为您应该专注于测试您的代码而不是 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-17
      • 2017-10-13
      • 1970-01-01
      • 2016-04-20
      • 2021-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多