抽象方法

时间:2015-05-04 15:02:58

标签: java spring junit mockito

我有一个抽象方法checkStatus(),它在Checker.java类中有实现。但是当我在抽象类方法validate()上执行Junit测试用例时,它反过来调用checkStatus(),由于缺少Checker.java类中的Spring依赖性而失败。

下面提供的详细信息。

抽象类:

public abstract class MyAbstractClass
{
    protected abstract boolean checkStatus();

    public boolean validate()
    {
        //Some code
        return checkStatus();
    }
}

实施班:

public class Checker extends MyAbstractClass
{
    @Autowired
    private StatusHelper helper;

    public void setHelper(StatusHelper helper){
        this.helper = helper;
    }

    @Override
    public boolean checkStatus() throws Exception{
        if(null == helper){
            throw new Exception("Helper is null");
        }

        return helper.validateStatus();
    }
}

JUnit测试:

class AbstractClassTest
{
    MyAbstractClass absClass = Mockito.mock(Checker.class, Mockito.CALLS_REAL_METHODS);

    @Test
    public void testStatusOfChecker()throws Exception {
        boolean status = absClass.validate();
        assertEquals(status, true);
    }
}

我相信我可以手动注入辅助对象,如下所示

Checker check = mock(Checker.class);
StatusHelper helper = mock(StatusHelper.class);
check.setHelper(helper);

但问题是,我无法直接注入absClass对象,因为setHelper()未被继承。

我可以直接将测试用例写入子类,但我需要这种方法来测试抽象类的validate()方法中的其他一些功能。

有人可以帮助我如何将辅助对象设置为子类,或者在Junit中有不同的方法吗?任何包含相关信息的帮助或链接都非常值得注意。 谢谢,

1 个答案:

答案 0 :(得分:2)

测试抽象类的唯一方法是测试一个实现(可能是一个匿名类)。

public class AbstractClassTest {
  @Test
  public void testStatusOfChecker() throws Exception {
    MyAbstractClass object = new MyAbstractClass() {
      protected boolean checkStatus() {
        return true; //this is the place to provide the expected value
      }
    }
    boolean status = absClass.validate();
    assertEquals(status, true);
  }
}

如果你想测试Checker实现,那么你不能嘲笑它。

public class CheckerTest {
  @Test
  public void test() {
    StatusHelper helper = mock(StatusHelper.class);
    Checker checker = new Checker();
    checker.setHelper(helper);
    when(helper.validate()).thenReturn(true);
    boolean status = checker.validate();
    assertEquals(status, true);
  }
}

顺便说一下,我强烈建议使用构造函数注入(参见Why field injection is evil)。然后测试看起来像这样

public class CheckerTest {
  @Test
  public void test() {
    StatusHelper helper = mock(StatusHelper.class);
    Checker checker = new Checker(helper);
    when(helper.validate()).thenReturn(true);
    boolean status = checker.validate();
    assertEquals(status, true);
  }
}