1

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

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

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

它是否正确?或者我是否需要在测试 Y 类时模拟 X 类或完全做其他事情?如果是这样,或者我应该模拟 X 班,那是什么原因?

4

3 回答 3

2

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

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

于 2013-09-15T23:44:49.250 回答
1

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

于 2013-09-15T23:45:00.893 回答
1

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

我的理由是:

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

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

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

  • 由于您的 X 类已经编写并且不包含什么都不做的方法,因此您不能将它用于 Y 类的单元测试。

  • 要考虑的另一点是如何在使用“真实”类 X 时模拟失败。您如何向 Y 提供 X 以使 X 总是导致异常,以便测试 Y 在面对不可靠的 X 依赖项时的行为?唯一明智的解决方案是使用 X 的 Mock/Stub。(当然,您的单元测试可能不会达到这种详细程度,因此我仅举个例子)

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

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

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

于 2013-09-16T00:20:04.173 回答