假设另一个单元测试已经测试了单元代码中断隔离的输入



我知道单元测试必须尽可能隔离,即自包含,不必依赖外部资源,如数据库、网络访问甚至执行以前的单元测试。

但是,假设我想测试类 Y.类 Y 使用类 X。但是,我已经有许多测试X类的单元测试。

我认为在 Y 类的单元测试中,

我可以假设 X 类工作正常,并使用它的实例化来测试 Y 类(在 Y 类单元测试中实例化,因此没有残留物或其他污染)。

这是对的吗?还是我需要在测试Y类时模拟X类或完全做其他事情?如果是这样,或者我应该模拟X班,这是什么原因?

类 Y

的单元测试应该只测试类 Y 的代码。您应该假设 Y 类所依赖的所有内容都已经在工作(并经过测试)。这是标准的单元测试。您希望减少外部依赖关系,并尝试隔离测试,以便实际上只在 Y 类的测试中测试 Y 类的功能,但在现实世界中,一切都是相互关联的。

在我看来,使用类 X 并假设它有效比模拟类 X 以提供更纯粹的单元隔离要好得多。无论哪种方式,您都应该假设 X 类是一个黑盒并且它有效。

我将在这里扮演魔鬼的代言人,并建议除非这是某种集成测试,否则不要在 Y 类测试中使用 X 类,而是使用 Mock(甚至存根)。

我这样做背后的理由是:

  • 如果你对 Y 的测试依赖于 Y 调用的 X 的一些副作用或状态,那么根据定义,它不是单元测试。

  • 因此,在 Y 类的
  • 单元测试中,你想要的只是外观和行为类似于 X 类的东西,同时完全由驱动类 Y 的测试方法定义并受其控制

  • 由于假设与单元测试相反,如果你想确保在 Y 测试期间调用 X.SomeMethod 时没有任何爆炸,那么 100% 确定(因此对测试有 100% 的信心)的唯一方法是通过 Mock 或存根提供X.SomeMethod的实现,你可以保证它不会失败,因为它什么都不做,因此不可能失败。

  • 由于您的类 X 已经编写并且不包含不执行任何操作的方法,因此您不能将其用于类 Y 的单元测试。

  • 要考虑的另一点是,在使用"真实"类 X 时如何模拟故障。您如何提供 X 到 Y,以便 X 总是导致异常,以测试 Y 在面对狡猾的 X 依赖项时的行为?唯一合理的解决方案是使用 X 的 Mock/Stub(当然,您可能不会在单元测试中达到这种详细程度,所以我只是举个例子)

  • 考虑一下 6 个月后,当您未正确单元测试的 X 类更改(遗漏测试、设计测试中的真正错误等)导致在 Y 类测试期间调用 X.SomeMethod 时引发异常时会发生什么。

  • 你怎么能立即知道问题是X类?还是真的是Y级?您不能,因此失去了独立单元测试的主要好处。

当然,当您继续进行集成测试时,您将使用类 X 来测试类 Y 在生产环境中的行为方式,但这是一个完全不同的问题......

这取决于你想成为一个纯粹主义者。如果 X 类只是另一个不依赖于外部资源(如数据库等)的类,我不会发疯并模拟 X 类。重要的是,您的代码具有完整的测试覆盖率。IMO 如果已经测试的代码在其他测试中作为"受信任代码"运行,这不是问题。

最新更新