在 Roy Osherove 的书 [单元测试][1] 书中,他解释说单个单元测试应该包含 0 到 1 个模拟。 他建议,如果您的测试没有对模拟进行断言,那么根本不要使用模拟。 他进一步演示了如何使用隔离框架来生成存根,其创建方式与模拟类似。 他对每个测试创建的存根数量没有建议限制。
我的问题是:这些建议是否可以应用于所有隔离框架(或所有流行的 C# 框架)? 换句话说,是否有一个框架只能生成模拟而不是存根? 是否有一个不区分模拟和存根的隔离框架?
我只是好奇 Osherove 的建议如何容易地转化为编码标准。
[1]: http://the 被测系统甚至根本没有经过测试,而是从模拟返回的数据正在被测试。
Philip Calçado 最近写了有关此内容的文章:https://philcalcado.com/2010/12/14/one_mock_per_test_considered_not_awesome.html。简而言之,他说,专注于测试中有多少模拟/存根会分散你的注意力,让你忽视应该主要关注的问题:编写良好的规范。
这直接对应于 Osherove 的建议,即每次测试仅执行一个断言。在他的词典中,
stub
是一个为被测系统提供假输入的类,而mock
是一个允许您测试被测系统输出的类(使用假类)。
框架是否使用类似的命名约定取决于其设计者,但标准(如果您同意他的建议)应该是每次测试仅执行一个断言,并且断言需要一个假对象 - 仅一个假对象每次测试都应该测试对象。
当然,并不是所有人都同意他的建议,所以也不是所有人都这样做。
有像 Moq 这样的框架并不区分它们。 FakeItEasy 更进一步,将所有东西称为假对象。
是的,它们可以应用,因为模拟只是更智能的存根。只要您不对多个模拟进行断言,即使存根被称为模拟也没有多大关系。换句话说,该建议更多的是关于每次测试仅断言一件事。明确区分模拟和存根并不那么重要。
> can those recommendations
> [a single unit test should contain between 0 and 1 mocks]
> be applied to all isolation frameworks ?
我认为:大多数时候是的如果你假设这些定义
这种规则应该被视为“训练轮”。显然,包含许多存根和模拟的测试已经失去了情节,但坚持每个测试一个断言或期望太严格了。正如引用的 Calçado 链接所指出的,重要的是每个测试都有一个“概念”,这可能涉及一些断言或期望来阐明这一点。您最不应该做的就是执行这样的标准。 还有一件事,我们真的应该在这里谈论“期望”,个体交互,而不是整个模拟对象。在实践中,它们通常是相同的,但它模糊了概念。