模拟父母最终方法

时间:2016-06-16 09:00:25

标签: java junit mockito

我想模拟一个继承的子类方法。这个方法不能被覆盖,因为它是最终的。当使用" 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 个答案:

答案 0 :(得分:2)

有两个理由可以提出这个问题:

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

b)你正在进行单元测试"错误:你从不创建一个B类的模拟对象,以便在B类上测试一些东西。你只能模拟你B中的代码需要做某事的对象X,Y,Z。

所以,你真正的问题是:你有一些方法" doSomethingElse()"在B上你想测试。并且" 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上定义了一些子类可以使用(或间接使用)并且 不会改变的行为。所以,你可以回到你的设计,也许最终被添加了#34;由于错误的原因",那么简单地删除关键字就可以了。