我是Angular的新手,正在进行单元测试。
我试图证实我对Fakes vs Spies(spyOn)的理解。
我的理解是Fakes允许您模拟实际上没有从服务返回的数据。它只是模拟它从服务传递。
另一方面,间谍让你实际上可以打电话或监视一项服务并获得一个真实的结果,以便在你的测试中进行比较。我说错了吗?
答案 0 :(得分:5)
以下是一些可以帮助您更好地发挥作用的信息:
虚拟对象传递但从未实际使用过。通常它们只用于填充参数列表。
伪对象实际上有工作实现,但通常需要一些使它们不适合生产的快捷方式(内存数据库就是一个很好的例子)。
存根为测试期间的调用提供固定答案,通常不会对测试中编程的任何内容做出任何响应。
间谍是根据调用方式记录某些信息的存根。其中一种形式可能是电子邮件服务,它记录发送的邮件数量。
模拟是我们在这里讨论的内容:预先编程了预期的对象,这些对象形成了预期会收到的呼叫规范。
现在您知道存根和间谍之间有什么区别,这里有更多信息可以解释它更好:)
测试double是一个可以代表测试中的真实对象的对象,类似于特技双重代表电影中的演员。这些通常都被称为“模拟”,但重要的是要区分不同类型的测试双打,因为它们都有不同的用途。最常见的测试双打类型是存根,模拟和 fakes 。
存根没有逻辑,只返回您告诉它返回的内容。当您需要一个对象返回特定值以使您的测试代码进入某个状态时,可以使用存根。虽然手工编写存根通常很容易,但使用模拟框架通常是减少样板的便捷方法。
模拟对应该调用它的方式有期望,如果没有这样调用,测试应该会失败。模拟用于测试对象之间的交互,并且在没有其他可见状态更改或返回可以验证的结果的情况下非常有用(例如,如果您的代码从磁盘读取并且您希望确保它不会超过磁盘一个磁盘读取,您可以使用模拟来验证执行读取的方法只被调用一次。
虚假不使用模拟框架:它是API的轻量级实现,其行为类似于真实实现,但不适合生产(例如内存数据库)。当您无法在测试中使用真正的实现时(例如,如果实际实现太慢或通过网络进行通信),可以使用伪造。您不应该经常编写自己的假货,因为假货通常应由拥有真实实施的个人或团队创建和维护。
答案 1 :(得分:1)
这是我所学到和实践的...在这里记下它以帮助某人...请专家对此进行更正/编辑以改善它。
PREMISE :我们要测试调用服务的组件
拨打电话实际服务
它的作用 :“从服务中调用实际属性,方法” 最佳使用时间 :“想用我们的组件测试实际服务”
功能 “我们创建了自己的'模拟'服务,我们在其中定义每个服务的内容... 注意:当我们定义模拟类时,我们需要确保包含原始服务的所有属性/方法。“ 最佳使用时间 “当我们可能不知道服务的内部工作原理并且我们可能不在乎时,我们会使用所有属性/方法创建我们自己的服务,以返回我们想要的结果,并且主要是要测试组件以针对组件的结果来测试其功能。服务”
功能 “我们'扩展'原始服务,我们可以从原始服务中选择具有一个或多个方法/属性,并且可以选择自己添加/编辑一个或多个方法/属性。 最佳使用时间 “当我们可能不知道服务的内部工作原理并且我们可能不在乎,但是为了避免模拟假类并创建每个方法/属性时,我们扩展为仅创建我们想要的方法/属性版本测试”
功能 “间谍返回值就像我们调用实际服务一样,间谍无需担心/接触该服务即可执行此操作-当我们调用组件(访问此服务)而不是调用实际服务时,它将使用从我们返回的值间谍” 最佳使用时间 “当我们想从服务的特定方法中返回特定值时,该特定结果将被我们的组件用于其测试”
答案 2 :(得分:0)
有很多方法可以放置这个。
我将简单地给您答案。假设您有一个具有功能 foo()的服务 myService 。 Foo函数返回您的姓名。
现在,您将看到myService.foo()。这将获取有关函数foo的外部详细信息,即,一旦您开始监视该函数,就可以获取该函数被调用了多少次,传入了什么值或参数。该函数,您甚至可以显式地使foo()返回您选择的值。这些都通过茉莉花间谍程序完成。
现在,如果是模拟,那只是您提供的假数据。 例如,同一服务foo()返回您的名称。 您为myService编写了一个伪造的服务模拟(并将其命名为myServiceMock),并为函数foo()返回了另一个名称。然后您期望它会失败。
因此,模拟功能是相同的函数,但它返回您想要的值,因此您可能无法通过测试并通过许多场景。
我希望这会有所帮助。简单来说,这些就是模拟和间谍之间的区别。