unit-testing - 创建一个共享的模拟对象或每个单元测试一个

标签 unit-testing mocking

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

我是否应该创建一个共享函数,以返回模拟对象,该模拟对象具有针对大多数“测试”项目进行了模拟的所有适当方法和行为,并将该对象调用到我的单元测试中?还是应该将对象模拟到每个单元测试中,仅模拟该测试所需的行为(尽管有时我会多次 mock 同一行为)。

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

最佳答案

我不确定对此是否有商定的“当前看法”,但这是我的2美分。

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

就配置这些模拟而言,这取决于情况和测试方式。我的首选是在每次测试中以所需的最少配置量对它们进行配置。这是准确传达该测试要求其依赖项的一种好方法。在这些情况下,某些重复没有什么错。

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

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

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

值得尝试一些不同的方法,看看哪种方法对您有效。任何重复删除都需要在保持每个测试用例独立,简单,可维护和可靠的前提下进行平衡。如果发现由于少量更改而导致大量测试失败,或者您无法弄 list 个测试所需的配置,或者如果测试失败取决于测试的运行顺序,那么您将需要完善您的方法。

关于unit-testing - 创建一个共享的模拟对象或每个单元测试一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11967558/

相关文章:

java - 在单元测试中为 @Import spring 配置设置 @Value 属性?

unit-testing - 如何在 Clojure 中对副作用函数进行单元测试?

Android 模拟位置不适用于谷歌地图

mocking - 动态wiremock捕获路径参数并返回响应

java - 使用 Mockito 测试返回对象的方法

unit-testing - 我的代码真的不可单元测试吗?

c# - 使用 Nsubstitute 模拟 RestClient ExecuteAsync

python - 如何让 MagicMock 表现得像一个字典?

java - 如何使用 Mockito 模拟 void 方法

python - 如何将 python 模拟库和装饰器与 unittest 库一起使用?