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

标签 unit-testing testing language-agnostic mocking tdd

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

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

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

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

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

最佳答案

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) 中实现您刚刚对模拟所做的操作。无论哪种方式,您都必须记录您选择做的事情,直到您准备好回去做。

关于unit-testing - 在进行 TDD 时,何时实现新的模拟依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36643767/

相关文章:

android - 创建用于测试的模拟 Activity 的最快方法

ios - Xcode 单元测试 - 仅为设备构建时出现链接错误

python-3.x - 如何将 body 发送到 Falcon 中的 simulate_post

使用 PyTables 和 HDF5 进行 Python 单元测试

unit-testing - 可以在不更改任何代码的情况下对最初未设计的单元测试代码进行测试吗?

c# - .NET HashSet 的内部实现包含方法?

testing - 如何在测试期间设置 React 组件的宽度?

algorithm - 在进行指数搜索时,为什么我们选择指数的底数为 2?

language-agnostic - 使用大量静态方法是一件坏事吗?

language-agnostic - 超越简单编码 : Where to go from here?