简体   繁体   English

使用子类测试抽象类中的具体方法

[英]Testing concrete methods in abstract classes using subclasses

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

I want to test concrete methods in abstract class.我想测试抽象类中的具体方法。 Is it ok if I test the concrete methods in base class in the unit test for any of the two derived classes, or is there any other way?如果我在单元测试中为两个派生类中的任何一个测试基类中的具体方法是否可以,或者还有其他方法吗?

So, if write test for DerivedOne class, it will include test for all methods AND the concrete method of the base class as well.因此,如果为 DerivedOne 类编写测试,它将包括对所有方法以及基类的具体方法的测试。 I know there is a thing "Mockito.CALLS_REAL_METHODS", using which we can test abstract classes, but in my case my base class has some dependencies which I initalise/inject using super() insider constructor of my derived classes, so I cant be doing it using CALLS_REALS_METHODS我知道有一个东西“Mockito.CALLS_REAL_METHODS”,我们可以使用它来测试抽象类,但在我的情况下,我的基类有一些依赖项,我使用派生类的 super() 内部构造函数初始化/注入,所以我不能使用 CALLS_REALS_METHODS 来做

There are two options which immediately come to mind here.这里有两种选择。

Firstly, you could write an abstract test class, which handles testing these methods, and then the test classes for your concrete implementations do the rest.首先,您可以编写一个抽象测试类来处理这些方法的测试,然后由具体实现的测试类完成剩下的工作。 For example:例如:

public abstract class YourAbstractClassTest {

    protected abstract YourAbstractClass getInstance();

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

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

Alongside:旁边:

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

You could also create a dummy subclass in a test class for it:您还可以在测试类中为它创建一个虚拟子类:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM