首页 文章

模拟父母最终方法

提问于
浏览
0

我想模拟一个继承的子类方法 . 这个方法不能被覆盖,因为它是final.When使用“when,thenReturn”mockito调用真正的方法导致一些异常,我想避免这种情况 .

class A{
    final String doSomething()
    {
        //Some treatement 
        return "";
    }
}
class B extends A{
    //
}

class TestB {
    @Test
    public void test(){}
    B b=mock(B.class);
    when(B.doSomething()).thenReturn("");// it fails because it calls //the real method of A
}

}

1 回答

  • 2

    有两个原因可以提出这个问题:

    a)您正在处理某些您无法改变的第三方库/设计;但你不知怎的想要测试 . 在这种情况下,使用PowerMock可以是一个选项,因为PowerMock操作字节代码并且可以模拟最终的方法/类 . 但是:PowerMock以创造各种怪异问题而闻名;并且认真地说:你最好不要使用它 .

    b)你得错"unit testing"错误:你 never 创建了一个B类的模拟对象,以便在B类上测试一些东西 . 你只模拟你B中的代码需要做某事的对象X,Y,Z .

    所以,你真正的问题是:你在B上有一些想要测试的方法“doSomethingElse()” . 并且“doSomethingElse()”调用“doSomething()”...并且您的测试失败,因为您无法控制“doSomething()”的行为 . 有两种方法可以摆脱这个问题:

    1)你真的需要继承吗?必须B真的扩展A,或者如果B对象...只是拥有一个A对象会更好吗? (如果是这样,你可以模拟A对象并获得对其方法的控制) . 有没有听说CoI

    2)你反向依赖;像:

    abstract class A { 
      final void doSomething() { doSomethingSpecific() ... }
      abstract void doSomethingSpecific();
    }
    
    class B extends A { @Override void doSomethingSpecific() { ...
    

    为您的“测试”问题提供“适当的OO”解决方案 .

    此外:如果"doSomething()"在A类上是最终的,那么这应该是为了实现OCP:你在A上定义一些子类可以使用(或间接使用)并且 should 不会改变的行为 . 所以,你可以回到你的设计,也许最后添加了"for the wrong reason",那么简单地删除关键字可能没问题 .

相关问题