我知道如何使用这些术语,但我想知道单元测试是否有伪造、模拟和存根的公认定义?如何为您的测试定义这些?描述一下你可能会用到它们的场景。

以下是我如何使用它们:

Fake:实现接口但包含固定数据且没有逻辑的类。只是根据实现返回“好”或“坏”数据。

Mock:实现接口的类,允许从特定方法动态设置返回值/抛出异常,并提供检查特定方法是否被调用/未调用的能力。

Stub:类似于模拟类,只是它不提供验证方法是否被调用的能力。

模拟和存根可以手工生成,也可以由模拟框架生成。假类是手工生成的。我使用模拟主要是为了验证我的类和依赖类之间的交互。一旦我验证了交互并在代码中测试替代路径,我就使用存根。我使用伪类主要是为了抽象出数据依赖关系,或者当mock /存根太乏味而每次都无法设置时。


当前回答

这是一个让测试富有表现力的问题。如果我想让测试描述两个对象之间的关系,我就在Mock上设置期望。我存根返回值,如果我设置一个支持对象,让我在测试中有趣的行为。

其他回答

在Gerard Meszaros所著的《xUnit Test Patterns》一书中,有一个很好的表格给出了关于差异的很好的见解

你在它上面断言的东西叫做模拟对象。

其他帮助测试运行的东西都是存根。

它们都被称为Test Doubles,用于注入测试用例所需的依赖项。

存根: 它已经有一个预定义的行为来设置您的期望 例如,stub只返回API响应的成功案例

mock是更聪明的存根。您验证您的测试通过了它。 所以你可以让amock返回成功或失败成功取决于你的测试用例可以改变的条件。

我倾向于使用两个术语-假和Mock。

只有在使用像Moq这样的Mock框架时才使用Mock,因为当它使用new Mock<ISomething>()创建时,将其称为Fake似乎是不正确的-虽然从技术上讲,您可以使用Mock框架创建stub或Fakes,但在这种情况下这样称呼它似乎有点愚蠢-它必须是Mock。

其他都是假的。如果一个Fake可以被总结为一个功能降低的实现,那么我认为一个Stub也可以是一个Fake(如果不是,谁在乎呢,每个人都知道我的意思,而且从来没有人说过“我认为你会发现那是一个Stub”)

根据Vladimir Khorikov的《单元测试原则、实践和模式》一书:

Mocks: help to emulate and examine outcoming interactions. These interactions are calls the SUT makes to its dependencies to change their state. In other words it helps to examine the interaction (behaviour) of SUT and its dependencies. mocks could be : Spy : created manually Mocks : created using framework Stubs: helps to emulate incoming interactions. These interactions are calls the SUT makes to its dependencies to get input data. IN other words it helps to test the data passed to SUT. It could be 3 types Fake: is usually implemented to replace a dependency that doesn’t yet exist. Dummy: is hard-coded value. Stubs: Fledged dependency that you configure to return different values for different scenarios.