我想模拟一个继承的子类方法 . 这个方法不能被覆盖,因为它是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 回答
有两个原因可以提出这个问题:
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)你反向依赖;像:
为您的“测试”问题提供“适当的OO”解决方案 .
此外:如果"doSomething()"在A类上是最终的,那么这应该是为了实现OCP:你在A上定义一些子类可以使用(或间接使用)并且 should 不会改变的行为 . 所以,你可以回到你的设计,也许最后添加了"for the wrong reason",那么简单地删除关键字可能没问题 .