我知道如何使用这些术语,但我想知道单元测试是否有伪造、模拟和存根的公认定义?如何为您的测试定义这些?描述一下你可能会用到它们的场景。
以下是我如何使用它们:
Fake:实现接口但包含固定数据且没有逻辑的类。只是根据实现返回“好”或“坏”数据。
Mock:实现接口的类,允许从特定方法动态设置返回值/抛出异常,并提供检查特定方法是否被调用/未调用的能力。
Stub:类似于模拟类,只是它不提供验证方法是否被调用的能力。
模拟和存根可以手工生成,也可以由模拟框架生成。假类是手工生成的。我使用模拟主要是为了验证我的类和依赖类之间的交互。一旦我验证了交互并在代码中测试替代路径,我就使用存根。我使用伪类主要是为了抽象出数据依赖关系,或者当mock /存根太乏味而每次都无法设置时。
单元测试——是一种控制单元(类、方法)的测试方法。
Test double -不是一个主对象(来自OOP世界)。这是一种临时创建的实现,用于测试、检查或在开发期间。它们是为关闭被测试单元(方法、类……)的依赖关系而创建的。
测试双工类型:
伪对象是接口(协议)的真实实现或扩展,它使用继承或其他方法来创建- is依赖。通常,它是由开发人员创建的,作为替代某些依赖项的最简单解决方案
存根对象是一个裸对象(0,nil和没有逻辑的方法),具有(由开发人员)预定义的额外状态,以定义返回值。通常是由框架创建的
class StubA: A {
override func foo() -> String {
return "My Stub"
}
}
模拟对象与存根对象非常相似,但是额外的状态在程序执行期间被改变,以检查是否发生了什么(方法被调用,参数,时间,频率……)
class MockA: A {
var isFooCalled = false
override func foo() -> String {
isFooCalled = true
return "My Mock"
}
}
间谍对象是一个具有“部分嘲讽性”的真实对象。这意味着除了模拟行为外,您使用的是一个非双精度对象
虚拟对象是运行测试所必需的对象,但该对象的任何变量或方法都没有被调用。
Stub vs mock
马丁·福勒说
存根使用状态验证,而mock使用行为验证,这是不同的。
[Mockito mock vs spy]