Тестирование конкретных методов в абстрактных классах с использованием подклассов - PullRequest
0 голосов
/ 27 февраля 2020
abstract class BaseClass{

      private final Dependency dep;

      BaseClass(final Dependency dep){
             this.dep = dep;
      }
      abstract void toBeImplementedBySubclasses();

      public int concreteMethod(){
              //Do some processing
              return any_integer;
      }
}
class DerivedOne{

      @Inject
      DerivedOne(final Dependency dep){
          super(dep);
      }       

      public void toBeImplementedBySubclasses(){
           //DO SOMETHING RELEVANT TO DERIVED ONE IMPLEMENTATION
      }
}
class DerivedTwo{

      @Inject
      DerivedOne(final Dependency dep){
          super(dep);
      }   

      public void toBeImplementedBySubclasses(){
           //DO SOMETHING RELEVANT TO DERIVED TWO IMPLEMENTATION
      }
}

Я хочу проверить конкретные методы в абстрактном классе. Это нормально, если я тестирую конкретные методы в базовом классе в модульном тесте для любого из двух производных классов, или есть какой-либо другой способ?

Итак, если написать тест для класса DerivedOne, он будет включать тест для всех методов И конкретного метода базового класса. Я знаю, что есть вещь "Mockito.CALLS_REAL_METHODS", с помощью которой мы можем тестировать абстрактные классы, но в моем случае у моего базового класса есть некоторые зависимости, которые я инициализирую / внедряю, используя конструктор инсайдеров super () моих производных классов, поэтому я не могу делать это с помощью CALLS_REALS_METHODS

1 Ответ

1 голос
/ 27 февраля 2020

Здесь сразу приходят на ум два варианта.

Во-первых, вы можете написать абстрактный класс test , который обрабатывает тестирование этих методов, а затем тестовые классы для вашего конкретного реализации делают все остальное. Например:

public abstract class YourAbstractClassTest {

    protected abstract YourAbstractClass getInstance();

    @Test
    public void testThing() {
        final YourAbstractClass instance = this.getInstance();
        instance.callMethod();

        Assertions.assertTrue(instance.someProperties());
    }
}

Рядом:

public class ConcreteSubclassTest extends YourAbstractClassTest {
    private final ConcreteSubclass instance = new ConcreteSubclass();

    @Override
    protected YourAbstractClass getInstance() {
        return this.instance;
    }

    @Test
    public void moreTesting() {
        this.instance.implementationSpecificMethod();
    }
}

Вы также можете создать для него подкласс dummy в тестовом классе:

public class AbstractClassTest {
    private final AbstractClass instance = new AbstractClass() {
        @Override
        public void abstractMethod() {
            throw new UnsupportedOperationException();
        }
    }

    @Test
    public void testThing() {
        this.instance.concreteMethod();
        // Just make sure this doesn't ever go near the
        // methods you dummied up above...
    }
}
...