我有一个“食谱”方法,我正在尝试使用 TDD 编写它。它基本上调用不同的方法,并偶尔根据这些方法的结果做出决策:
public void HandleNewData(Data data)
{
var existingDataStore = dataProvider.Find(data.ID);
if (data == null)
return;
UpdateDataStore(existingDataStore, data, CurrentDateTime);
NotifyReceivedData(data);
if (!dataValidator.Validate(data))
return;
//... more operations similar to above
}
我的本能 react 是开始编写测试用例,在其中验证 HandleNewData 调用上面看到的方法传递预期的参数,并且在方法调用失败的情况下返回。 但对我来说,这有点像是在编写这样的测试代码上投入了巨大的时间,几乎没有任何实际好处。
那么编写这样的测试的真正好处是什么?还是真的不值得这么麻烦?
这似乎只是代码本身的过度规范,每当该代码必须调用另一个方法或决定不再调用当前方法之一时,就会导致维护问题。
最佳答案
TDD 并不意味着为已经存在的代码编写单元测试(尽管有时在改进遗留代码时可能有必要)。
您可能听说过“红、绿、重构”这个术语。这就是我们在进行 TDD 时采用的方法。以下是测试驱动开发的三个定律,它们更进一步......
- 您不得编写生产代码 直到你写了一篇失败的文章 单元测试。
- 您编写的单元测试不得超过足以失败的程度,并且 不编译就是失败。
- 您编写的生产代码不得超过足以通过测试的代码 目前测试失败。
采用这种方法的好处是,您最终会获得非常接近 100% 的单元测试覆盖率,并且您知道您的代码完全按照指定方式工作。
它将减少维护问题,因为一旦有人对您的代码进行更改并运行测试,他们就会知道他们是否破坏了任何内容。
在这种情况下,我会在为 HandleNewData()
添加任何单元测试之前,逐步为从 HandleNewData()
调用的方法添加单元测试。
向遗留代码添加单元测试很困难,但可行并且非常值得付出努力。如果您还没有,我强烈建议您阅读 Working Effectively with Legacy Code通过 Michael Feathers 。我发现在向已有 25 年历史的代码库中添加单元测试时,它非常有值(value)。
关于unit-testing - 单元测试理念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6103807/