当你尝试在项目中实现单元测试时,我一直在读静态方法,静态类和单例是邪恶的。在遵循TDD范例时,我是否应该忘记它们曾经存在过,从不再使用它们,或者有时可以使用它们吗?
答案 0 :(得分:10)
永远不要说永远 - 静态类和方法在你的工具箱中占有一席之地。
也就是说,如果你试图隔离和测试的类(测试对象或SUT)取决于静态类或方法,你将无法编写将SUT与静态依赖关系隔离的测试 - 当你的测试代码运行它仍然会使用静态调用。有时这很好,但有时你想创建一个独立的测试,只测试你的SUT的逻辑而没有依赖(通常通过模拟或类似的技术)。
一般来说,我个人比较谨慎地使用静态类和方法。
由于Singletons的实现方式,它们为隔离SUT进行单元测试提出了类似的问题。此外,GOF单例概念被一定比例的软件开发人员认为是不好的做法。我碰巧同意这种观点,但在这个问题上几乎没有达成共识。快速搜索谷歌可能会让你很好地了解GOF Singleton模式的优缺点。
答案 1 :(得分:3)
为了进一步解释最后一部分,尝试在构造函数参数中初始化值,而不是尝试从代码中的单例中检索值。如果构造函数变得太大,请创建一个用于创建的工厂方法,以便您可以在不使用单例的情况下测试类。如果这证明是有问题的,或者你的单身人士有可变状态(我会害怕,但嘿,那就是我)然后试着让你的单身人士尽可能容易地融入你的测试中。
您不希望创建整个配置文件只是为了测试类的方法,该类计算4小时内股票报价块的标准差。那工作太多了。但是如果你的单例以这样的方式编写,你可以用数据填充它,并让另一个类负责读取配置文件并填充这些数据,那么你已经取得了很大的进步。
关于静态方法,我认为它们是最容易测试的方法,你可以根据你不需要担心全局状态的条件来编写。静态相当于y = f(x)
,这似乎过于简单,但是没有本地状态转换可以改变不变量的事实,即对于给定的x
,您总是会得到相同的y
。
答案 2 :(得分:2)
与任何软件工程实践一样,任何情况都没有一个明确的解决方案。所以你永远不应该排除静态方法,静态类和单例。 TDD的目的是让您的生活更轻松,您会注意到,当您使用TDD更多地工作时,您的代码将是模块化的,这意味着即使您使用静态方法(...等),您的代码仍然是可测试的。< / p>
我喜欢的规则是:只要您的代码易于阅读且设计优雅,就可以使用您想要的任何内容。你如何实现这些2取决于你。如果你仍然可以提供优雅的代码,那么你可以使用GOTO。
答案 3 :(得分:-1)
我一直在读静态方法......当你尝试实施单元测试时是邪恶的
我从未读过这篇文章。你能提供参考吗?我会对此提出质疑。我一直使用和单元测试静态方法(函数),没有问题。
<强>被修改强>
感谢您提及Static Methods are Death to Testability: 那篇文章很垃圾。
静态方法的基本问题是它们是程序代码。我不知道如何对程序代码进行单元测试。
这表明autor对单元测试知之甚少。当然,您可以对程序代码进行单元测试。
在实例化过程中,我将依赖项与mocks / friendlies连接起来,取而代之的是真正的依赖项。
这是一个关键错误:单元测试需要模拟对象的想法。它不是。在任何情况下,您都可以将模拟对象作为参数传递给您正在测试的静态方法:依赖注入不需要构造函数。有关详细信息,请参阅the accepted answer of the question "Static Methods : When and when not"
如果静态方法调用另一个静态方法,则无法覆盖被调用的方法依赖项。
真实但无关紧要。如果静态方法 A 调用静态方法 B ,那就是方法 A 的实现细节。因此,您没有业务尝试来拦截对 B 的调用。只需将 A 视为一个单位。
假设您的应用程序只有静态方法
一个稻草人的论点。很明显,在现代单元测试的上下文中,我们讨论的是仅使用一些静态方法的OO程序。