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