首页 > 解决方案 > 使用子类测试抽象类中的具体方法

问题描述

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

标签: javaunit-testingmockitotestngabstract-class

解决方案


这里有两个选项立即浮现在脑海中。

首先,您可以编写一个抽象测试类来处理这些方法的测试,然后您的具体实现的测试类完成其余的工作。例如:

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

您还可以在测试类中为其创建一个虚拟子类:

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...
    }
}

推荐阅读