Тестирование default метода интерфейса

256
20 ноября 2017, 17:58

Подскажите пожалуйста, как можно красиво протестить дефолтный метод чтоб было как меньше дулирования кода, при вот таких условиях:

public interface Colorable {
     int getColor();
     default boolean validateColor(int color) {
         return color > 0; //Тут можно поменять getColor() > 0, если это принципиально
     }
}

Есть интерфейс и фигуры которые его имплементят(ColorLine, ColorTriangle, ColorPolygon). Я не хотел бы писать в ColorLineTest, ColorTriangleTest, ColorPolygonTest один и тот же юнит тест который проверяет работу этого дефолтного метода. Мне бы хотелось чтоб был какой-нибудь абстрактный класс в котором тестировался этот метод, и все классы типо ColorLineTest, ColorTriangleTest... просто унаследовали этот тест. А писать его нужно будет только если реализующий класс переопределит дефолтную логику.

Answer 1

Пришла мысль про наследование тестовых классов и создание абстрактных тестов, но нет пока времени проверить.

Создайте анонимный(mock) объект в классе теста (интерфейса), вам надо только переопределить не дефолтные методы интерфейса:

Colorable colorable = new Colorable(){
      public int getColor(){
          //логика работы метода для теста
      }
};

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

Answer 2
import org.junit.Test;
public abstract class ColorableTest {
    public Colorable colorFigure = new Colorable() {
       @Override
       public int getColor() {
        return 0;
       }
   };
   @Test
   public void testValidateColor() throws Exception {
       colorFigure.validateColor(911);
   }
}

Это то что вы подсказали, если я правильно понял

import model.interfaces.Colorable;
public class ColorPoint extends Point implements Colorable {
     private int color;
     public ColorPoint(int x, int y, int color) {
        super(x, y);
        if (!validateColor(color)) throw new IllegalArgumentException();
        this.color = color;
     }
     public ColorPoint(Point point, int color) {
        this(point.getX(), point.getY(), color);
     }
     @Override
     public int getColor() {
        return 0;
    }
    public void setColor(int color) {
         if (!validateColor(color)) throw new IllegalArgumentException();
         this.color = color;
    }
    ...
 }

Это один из наследников Colorable и вот его тест:

import model.interfaces.ColorableTest;
import org.junit.BeforeClass;
public class ColorPointTest extends ColorableTest{

    @BeforeClass
    public void setUp() throws Exception {
        this.colorFigure = new ColorLine(new Point(1, 1), new Point(1, 1), 911); //Вот здесь проблема
    }
}

Получается чтоб подставить конкретную реализацию нужно проинициализировать переменную colorFigure, и выход что если она нормально создалась то необходимости в тесте нету, а если нет то она упадет до теста.

READ ALSO
Скачивание из Dropbox API v2 Java SDK

Скачивание из Dropbox API v2 Java SDK

Кто-нибудь может объяснить как скачать текстовый файл из Dropbox API v2В интернете в основном на устаревшую версию Dropbox API v1

232
Вопрос по finalize

Вопрос по finalize

Добрый день, сразу к делу, у меня в приложении куча сцен и каждая сцена - это свой объект, там иерархия своя естественно создано и тд

195
Не запускается меню “Debug Main” в Android Studio. Что делать?

Не запускается меню “Debug Main” в Android Studio. Что делать?

При запуске меню "Debug Main" в Android Studio 30 выдаёт эту ошибку:

290