在子类中模拟/测试超类调用。它可能吗?

时间:2011-12-14 14:17:17

标签: unit-testing seam mockito easymock jmock

我正在寻找在子类ButtonClicker中模拟超级调用的解决方案。

Class Click {
      public void buttonClick() throws java.lang.Exception { /* compiled code */ }     } 

Class ButtonClicker extends Click { 
    @Override
    public void buttonClick() throws Exception {

        super.buttonClick();
    } }

2 个答案:

答案 0 :(得分:6)

使用继承会降低代码的可测试性。考虑用delegation替换继承并模拟委托。

提取接口IClicker

interface IClicker {
    void buttonClick();
}

IClicker课程中实施Clicker。如果您正在使用第三方代码,请考虑使用Adapter Pattern

重写您的ButtonClicker,如下所示:

class ButtonClicker implements IClicker {
    Clicker delegate;

    ButtonClicker(Clicker delegate) {
        this.delegate = delegate;
    }

    @Override
    public void buttonClick() throws Exception {
        delegate.buttonClick();
    }

}

现在只需将mock作为构造函数参数传递:

Clicker mock = Mockito.mock(Clicker.class);
// stubbing here
ButtonClicker buttonClicker = new ButtonClicker(mock);

答案 1 :(得分:3)

答案是否定的。模拟只是一个简单的接口实现。 (我的意思是API意义上的接口,而不是特定的Java关键字意义。)所以它不知道任何实现细节,比如哪个类实际实现了功能(实质上没有功能)。

你可以在一个真实对象上创建一个“间谍”,让你只模拟一些方法而不是其他方法,但这也不会让你只是模拟一个类的超级方法,因为你选择的方法mock通常由签名选择,对于子类和超类都是相同的。