2016-12-10 8 views
1

У меня есть небольшая проблема с моими модульными тестами для приложения Swing. Что я хочу сделать, так это передать объект, пригодный для рисования, в мой JPanel, и каждый раз, когда я делаю это, он должен перекрашиваться.Как создать макет JFrame/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 и просто устанавливает флаг в 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 не красилась. Однако, когда я на самом деле запускаю программу и добавляю новую графическую линию, она отлично работает, все мои фигуры окрашиваются. Я что-то пропустил в тестовой настройке?

Более того, и это, вероятно, самая важная часть, я думаю, что это не оптимальное решение для запуска целого JFrame каждый раз, когда я запускаю свои тесты, поэтому мне было интересно, как мне лучше всего создать тестовый двойник, не разрушает всю функцию перерисовки.

Заранее благодарим за любые намеки!

ответ

0

Я думаю, вы должны сосредоточиться на тестировании вашего кода вместо реализации 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); 
    } 
}