【问题标题】:Create a single shared Mock Object or one per Unit Test创建单个共享模拟对象或每个单元测试一个
【发布时间】:2012-08-15 10:15:38
【问题描述】:

我目前正在通过利用 Mock 对象(在这种特殊情况下为 nSubsitute)来扩展我的单元测试。但是我想知道创建 Mock 对象时当前的智慧是什么。例如,我正在处理一个对象,该对象包含各种获取和处理数据的例程 - 这里没什么大不了的,但它将在相当多的测试中使用。

我是否应该创建一个共享函数,该函数返回 Mock 对象,其中包含在大部分测试项目中模拟的所有适当方法和行为,并将该对象调用到我的单元测试中?或者我应该将对象模拟到每个单元测试中,只模拟该测试所需的行为(尽管有时我会多次模拟相同的行为)。

非常感谢您的想法或建议......

【问题讨论】:

    标签: unit-testing mocking


    【解决方案1】:

    我不确定这方面是否有公认的“当前智慧”,但这是我的 2 美分。

    首先,正如@codebox 指出的那样,为每个单元测试重新创建模拟是一个好主意,因为您希望单元测试彼此独立运行。否则会导致测试在一起运行时通过,但在单独运行时失败(反之亦然)。创建测试所需的模拟通常在测试设置中完成(NUnit 中的[SetUp],XUnit 中的构造函数),因此每个测试都会获得一个新创建的模拟。

    就配置这些模拟而言,这取决于具体情况和您的测试方式。我的偏好是在每个测试中使用最少的必要配置来配置它们。这是准确传达测试对其依赖项的要求的好方法。在这些情况下,有些重复并没有错。

    如果多个测试需要相同的配置,我会考虑使用scenario-based test fixture (链接免责声明:无耻的自我宣传)。场景可能类似于When_the_service_is_unavailable,并且该场景的设置可以配置模拟服务以引发异常或返回错误代码。然后,每个测试都会根据该常见配置/场景做出断言(例如,应该显示错误消息,应该向管理员发送电子邮件等)。

    如果您有很多重复的配置位,另一个选择是使用Test Data Builder。这为您提供了可重用的方式来配置模拟或其他任何其他测试数据的许多不同方面。

    最后,如果您发现需要进行大量配置,则可能值得考虑将测试依赖项的接口更改为不那么“健谈”。通过寻找一个有效的抽象来减少被测类所需的调用次数,您将在测试中配置更少,并且很好地封装了该类所依赖的职责。

    值得尝试几种不同的方法,看看哪种方法适合您。任何重复的删除都需要与保持每个测试用例独立、简单、可维护和可靠保持平衡。如果您发现大量测试因小的更改而失败,或者您无法确定单个测试所需的配置,或者如果测试失败取决于它们的运行顺序,那么您将需要完善你的方法。

    【讨论】:

      【解决方案2】:

      我会为每个测试创建新的模拟 - 如果您重复使用它们,您可能会出现意外行为,即早期测试的模拟状态会影响以后测试的结果。

      【讨论】:

      • 是的,但是嗯,我相信 OP 要求重新使用模拟实现,而不是重新使用它的单个实例。
      【解决方案3】:

      如果不看具体案例,很难提供一般性答案。

      我会坚持与其他地方一样的方法:首先将测试视为独立的存在,然后寻找相似之处并提取出共同的部分。

      您的目标是遵循DRY,以便您的测试在需求发生变化时可维护。

      所以...

      1. 如果很明显组中的每个测试都将使用相同的模拟行为,请在您的通用设置中提供它

      2. 如果它们中的每一个都显着不同,例如:模拟的内容构成了您正在测试的重要部分,并且测试/模拟关系看起来像 1:1,那么保留它们是合理的接近测试

      3. 如果模拟之间存在差异,但只是在某种程度上,您仍然希望避免冗余。普通的设置对您没有帮助,但您可能需要引入像 PrepareMock(args...) 这样的实用程序来涵盖不同的情况。这将使您的实际测试方法无需重复设置,但仍然可以让您在它们之间引入任何程度的差异。

      当您向上提取所有相似性(到 SetUp 或辅助方法)时,测试看起来不错,因此测试方法中唯一剩下的就是它们之间的不同之处。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多