我想模拟一个继承的子类方法。这个方法不能被覆盖,因为它是最终的。当使用" 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
}
}
答案 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;由于错误的原因",那么简单地删除关键字就可以了。