Mockito的java局限性
我知道Mockito不支持模拟局部变量、静态方法和私有方法。有没有办法绕过它
就像在私有方法的情况下,将方法从私有更改为私有就可以了,或者我们可以将其更改为受保护的接口,以便编写测试脚本。那么,对于静态方法和局部变量,我们有类似的东西吗
https://github.com/mockito/mockito/wiki/FAQ说Mockito的局限性。如果Mockito大师还有其他限制,以及如何克服这些限制,我指的是重构。多谢各位
你可以在下面搜索框中键入要查询的问题!
我知道Mockito不支持模拟局部变量、静态方法和私有方法。有没有办法绕过它
就像在私有方法的情况下,将方法从私有更改为私有就可以了,或者我们可以将其更改为受保护的接口,以便编写测试脚本。那么,对于静态方法和局部变量,我们有类似的东西吗
https://github.com/mockito/mockito/wiki/FAQ说Mockito的局限性。如果Mockito大师还有其他限制,以及如何克服这些限制,我指的是重构。多谢各位
# 1 楼答案
避免Mockito局限性的最好方法是不要坚持编写独立的单元测试
与一些人的想法相反,单元测试不需要与被测试单元的依赖项隔离运行。作为described by Martin Fowler(正如TDD的“父亲”Kent Beck所实践的那样),单元测试可以是“社交的”(没有模仿依赖项)或“孤立的”(有模仿依赖项)
因此,避免这些模仿工具限制的一种方法就是不依赖它们。您可以通过编写“社交”单元测试来实现这一点,或者(像我一样)全程编写集成测试
提到的另一个“解决方案”是重构测试中的代码,以绕过模拟限制,或者“为模拟而设计”(正如Jeff Bowman所说)。 我希望大多数开发人员意识到这是一个糟糕的解决方案,因为它通常需要向SUT添加额外的复杂性,以弥补特定模拟库中的任意限制。 考虑增加^ {< CD1> }方法的可访问性的情况,这样您就可以直接测试它或模拟它。好吧,如果你觉得这是可以接受的,你真的关心代码质量吗?如果你不在乎,那为什么还要为自动化开发人员测试而烦恼呢
# 2 楼答案
为了帮助理解Mockito的局限性,了解Mockito为您做了什么是很重要的:Mockito为您传入的类创建了一个动态(基于代理的)子类<这意味着,就像您自己编写的子类一样,您将无法访问或控制私有字段和方法、静态方法和局部变量。没有解决办法
您在评论中提到了PowerMock,它通过重写要模拟的类的字节码,或者重写使用要模拟的类的类的字节码,从而绕过了Mockito的一些限制。这允许PowerMock拦截不能通过多态性覆盖的调用,特别是
private
、static
和final
字段。您也将无法访问局部变量相反,您最好的选择是重新构造类或方法,以便它确实能够提供您想要的控制。一般来说,您应该问“如果我创建了自己的子类,我是否能够做到这一点”,这个答案将有助于确定Mockito是否能够为您实现自动化
(注意,下面我提到的是“为模仿而设计的”,但您真正做的是为依赖项的替代实现而设计;模拟只是这方面的一个例子,还有许多其他的测试双重功能,比如假的或内存中的实现。记住,并不是所有的测试都需要模拟或替换,以保持单元测试;只需确保您在测试中的依赖关系是快速的、确定的,并且经过良好测试。相反,对于速度慢、不确定、测试不好或尚未编写的组件,用假组件或模拟组件替换实现可能会提高测试质量和覆盖率。)
一种技术是将依赖项作为方法参数传入
另一种是切换到完全依赖项注入:
最后,您可以创建一个可重写工厂方法,该方法引入Mockito基于子类的重写所需的多态性
另见:How to use Mockito when we cannot pass a mock object to an instance of a class