我一直在阅读使用TDD时往往会避免使用静态方法,因为它们往往难以模拟。我发现,单元测试最简单的方法是一个具有简单功能的静态方法。不必实例化任何类,鼓励简单,做一件事,“独立”等方法。
有人可以解释TDD最佳实践与实用轻松之间的差异吗?
感谢, 甲
答案 0 :(得分:14)
静态方法很容易测试,但是直接调用静态方法的东西通常不容易独立于它依赖的静态方法进行测试。使用非静态方法,您可以使用存根/模拟/假实例来简化测试,但如果您正在测试的代码调用静态方法,则它实际上与该静态方法“硬连线”。
答案 1 :(得分:3)
问题的答案是,在我看来,“面向对象似乎是TDD人们所想的全部内容”。
为什么呢?我不知道。也许他们都是Java程序员,他们已经感染了使一切依赖于六个间接层,依赖注入和接口适配器的疾病。
Java程序员似乎喜欢预先让一切变得困难,以便“以后节省时间。”
我建议在您的TDD中应用一些敏捷原则:如果它没有引起问题,那么就不要修复它。不要过度设计。
在实践中,我发现如果首先测试静态方法,那么它们不会成为调用者中的错误的原因。
如果静态方法快速执行,那么它们就不需要模拟。
如果静态方法使用程序外部的东西,那么您可能需要一个模拟方法。在这种情况下,您需要能够模拟许多不同类型的函数行为。
如果你确实需要模拟静态方法,请记住有办法在OO编程的外。
例如,您可以编写脚本来将源代码处理为调用mock函数的测试表单。您可以将具有不同版本功能的不同目标文件链接到测试程序中。您可以使用链接器技巧来覆盖函数定义(如果它没有内联)。我相信还有一些我没有在这里列出的技巧。
答案 2 :(得分:2)
测试静态方法很容易。问题是在测试其他代码时无法将其他代码与静态方法隔离开来。调用代码与静态代码紧密耦合。
对静态方法的引用不能被许多模拟框架嘲笑,也不能被覆盖。
如果你有一个正在进行大量静态调用的类,那么要测试它,你必须为所有这些静态调用配置应用程序的全局状态 - 所以维护变成了一场噩梦。如果您的测试失败,那么您不知道哪个位代码导致了失败。
错误,是许多开发人员认为TDD无意义的原因之一。他们为测试结果付出了巨大的维护费用,只是模糊地指出出了什么问题。如果他们只减少了他们的代码单元之间的耦合,那么维护将是微不足道的,并且测试结果是特定的。
答案 3 :(得分:0)
这个建议在大多数情况下都是正确的......但并非总是如此。我的评论不是特定于C ++的。
让我们举个例子
public class MyStaticClass
{
static int __count = 0;
public static int GetAddCount()
{ return ++__count; }
public static int Add(int operand1, int operand2)
{ return operand1 + operand2; }
// needed for testability
internal static void ResetCount()
{
__count = 0;
}
}
...
//test1
MyStaticClass.Add(2,3); // => 5
MyStaticClass.GetAddCount(); // => 1
// test2
MyStaticClass.Add(2,3); // => 5
//MyStaticClass.ResetCount(); // needed for tests
MyStaticClass.GetAddCount(); // => unless Reset is done, it can differ from 1