在进行TDD时,何时实现新的模拟依赖项?

时间:2016-04-15 09:48:35

标签: unit-testing testing language-agnostic mocking tdd

有一个问题我无法找到答案,关于TDD采用从外到内的方法:

我实现了一个新单元(A),为它编写了一个测试,这个单元需要一个尚不存在的依赖(B)。在我的测试中,很容易模仿这种依赖,但我在生产代码中该怎么办?

我是否首先执行(B)并让我对(A)的测试同时失败,因为我还没有继续实现它以使测试通过呢?

或者我首先完成(A)同时让(B)的测试失败,因为它例如只返回“空”对象,而不是实际执行其规范告诉它做的事情?

或者我应该让(B)的测试暂时检查它是否会在我继续执行时返回“空”对象(A) - 尽管这实际上并不是(B)的规范是什么?

2 个答案:

答案 0 :(得分:3)

TDD的基本策略是保持所有测试通过,除了您正在进行的测试。在您担心(B)之前,让(A)的测试通过。

您为类(A)及其复杂依赖项(B)编写测试和代码的顺序是

  • 为(A)编写测试。 [套房是红色的。]
  • 开始实施足够的(A)以获得刚刚写完的测试。发现你需要的(B)。 [套房是红色的。]
  • 模拟(B)。 [套房是红色的。]
  • 完成你刚刚写完的(A)考试。 [套房是绿色的。啊!]重构。
  • 如果您还没有(A)处于良好的停留点,请返回顶部并重复,直到您处于(A)的良好停靠点。
  • 为(B)编写一个测试,要求(B)完成(B)模拟的部分或全部。 [套房是红色的。]
  • 进行刚刚写完的测试。 [套房是绿色的。啊!]重构。
  • 如果你还没有复制(B)的模拟在(B)的测试和代码中做的所有内容,请返回两步并重复,直到你复制了所有的模拟(B)确实。

此时,您可以选择在(A)或(B)上工作更多或开始新事物。

尽管此策略始终使测试通过,但它并不能确保您的应用程序立即执行某些有用的操作。确保您的应用程序最终执行某些有用的操作的方法超出了TDD:首先编写验收测试(针对整个应用程序运行而不运行模拟)和TDD,直到验收测试和您的单元测试全部通过。 (有关详情,请参阅。)

验收测试(或其他集成测试)还确保您在模拟类的测试和代码中正确复制模拟。

另请注意,跟踪您已经考虑但尚未实施的要求,或者您已实施的要求至关重要。仅在模拟中,需要在模拟依赖项的测试和代码中实现。这就是为什么TDD By Example和TDD如何完成的其他例子之所以如此谈论实际或精神待办事项清单。对于具有模拟依赖关系(B)的类(A),在编写模拟之后,您可以返回工作(A)或在(B)中实现您对模拟执行的操作。无论哪种方式,你必须跟踪你选择的内容,直到你准备回去做它。

答案 1 :(得分:0)

我建议只在你的代码中真正需要B时才依赖于B.如果A中的任何内容都不依赖于B,为什么要在此阶段添加它?

如果您的代码现在确实需要B,为什么不开始实现您现在需要的B功能呢?

当然,如果它没有任何逻辑,你也可以在代码中使用虚拟对象而不是B。否则我会开始实施B.