Mockito不允许嘲笑最终方法。 在代码中使用最终方法被认为是不好的做法吗?为什么?
我不想仅仅为了使测试代码工作而改变实现细节,但是,测试框架通常会有这些规则来鼓励更好的编码实践。
答案 0 :(得分:5)
final
方法一般来说绝对不是坏习惯:它们传达了一个关于方法的行为和语义的特定信息 - 即,任何调用该方法的人都将获得完全相同的实现。 这正是您试图通过模拟破坏的属性,因为您通过(动态生成的)子类覆盖最终实现来代替执行存根行为。
为此,如果您有一个实现,您可以控制您尝试使用存根替换测试,那么它可能不应该是final
,因为您将其视为非{ {1}}在测试中使用自己的方法。您的测试是组件的另一个用户,也是您可以相应设计的用户。
在您无法控制的实现中,例如第三方库,PowerMock是一种普遍接受的模拟构造函数的解决方案,以及final
,private
和{{1方法,可能在static
类中。但是,PowerMock确实存在一些危险:
final
方法,因此Powermock可以替换这些调用。final
修饰符的语义,可能会使您的代码难以阅读 - 您声明方法有一个明确定义的可预测行为,然后解决您自己的声明。就“最佳做法”而言,真正的最佳做法是OOP原则jgitter上面提到:“Program to interfaces, not implementations.”依靠显式接口:
final
方法,测试不可见的方法或methods in superclasses not visible to the test等实现细节。最终方法特别隐蔽,因为Mockito can't warn you about them。也就是说,Mockito存在具体类的简易性使其成为一个诱人的选择,但要注意最简单的语义正确答案可能只是从特定的static
删除需要存根的方法。
答案 1 :(得分:2)
我相信使用final关键字是一种很好的方式,可以让未来的开发团队明白特定的方法或类是有意无法覆盖的。这些限制也让我感到烦恼。现代Web容器也代理池化bean(等),同样的问题出现在那里。
我建议调查PowerMock。它们提供了很好地插入Mockito的实现。
https://code.google.com/p/powermock/
- 编辑 -
由于害怕开始圣战,我还想说,通常,你应该在界面中测试暴露的API,并且任何最终方法都将通过该界面间接测试。但是,如果你有一个高风险的方法,那么深入了解它是有用的。
答案 2 :(得分:0)
当您不让其他程序员覆盖该方法时,我发现最终关键字对方法很有用。
例如,我有一个三角类,发现两边的直角三角形的斜边是一边的法律平方根,一边是2的力量,另一边是b的2的幂。那是' sa数学定律。阻止程序员覆盖它并可能犯错误。使方法最终public class Trig
{
public final double hytpotenuseOfRightTriangle(double sideA, double sideB)
{
return Math.sqrt(Math.pow(sideA, 2) + Math.pow(sideB, 2));
}
}