在单元测试期间,监视方法什么时候有用



使用Jasmine可以使用spyOn方法,但我不清楚它什么时候真正有用。我的理解是,单元测试不应该关注实现细节,若方法被调用,则测试将是实现细节。

我可能会想到的一个地方是监视scope.$broadcast(Angular)等,但这将是实现细节,并且不确定单元测试是否应该关心代码的工作方式,只要它能给出预期的结果。

显然有充分的理由使用spyOn,那么什么地方是使用它的好地方呢?

您描述的spyOn在测试中更常见为MOCK,尽管更清楚地说,它允许两种操作:

  1. 通过createSpy(这是经典的mock)为方法创建一个新的实现

  2. 通过spyOn检测现有方法(这允许您查看该方法是否被调用,以及使用什么参数、返回值等)

模拟可能是单元测试中最常用的技术。当你测试一个代码单元时,你经常会发现其他代码单元之间存在依赖关系,这些依赖关系有自己的依赖关系等。如果你试图测试所有东西,你最终会得到一个模块/UI测试,它既昂贵又难以维护(它们仍然很有价值,但你想要的尽可能少)

这就是嘲讽的用武之地。想象一下,您的单元为一些数据调用REST服务。您不希望在单元测试中依赖某个服务。因此,您可以模拟调用服务的方法,并提供自己的实现,只需返回一些数据。想要检查您的单元是否处理REST错误?让你的模拟返回一个错误。等

了解您的代码是否真的调用了另一个代码单元有时会很有用——想象一下,您希望确保您的代码正确地调用了日志模块。只需模拟(spyOn)该日志记录模块,并断言它被使用正确的参数调用了X次。

您可以监视函数,然后您将能够断言几件事关于它。你可以检查它是否被调用,它有什么参数,它是否
返回了什么,甚至它被调用了多少次!Spies在编写测试时非常有用,所以我将解释如何在这里使用它们中最常见的。

// This is our SUT (Subject under test)
function Post(rest) {
this.rest = rest; 
rest.init();
}

我们这里有我们的SUT,它是一个后构造函数。它使用RestService去拿它的东西。我们的岗位将把所有休息工作委托给RestService当我们创建一个新的Post对象时,它将被初始化。让我们开始测试一步一步:

`describe('Posts', function() {
var rest, post;
beforeEach(function() {
rest = new RestService();
post = new Post(rest);
});
});`

这里没有什么新鲜事。由于我们在每次测试中都需要这两个实例,我们将初始化放在beforeEach上,这样我们每时间在后创建时,我们初始化RestService。我们想测试一下,如何我们能做到吗?:

`it('will initialize the rest service upon creation', function() {
spyOn(rest, 'init');
post = new Post(rest);
expect(rest.init).toHaveBeenCalled();
});`

我们希望确保在创建新的张贴对象。为此,我们使用jasmine spyOn函数。第一个参数是我们要放置spy的对象和第二个参数是一个字符串代表间谍的功能。在这种情况下,我们想监视函数init关于间谍对象。然后我们只需要创建一个新的Post对象,该对象将调用init函数。最后一部分是断言rest.init呼叫。很简单吧?重要的是,当你监视函数,则永远不会调用真正的函数。所以在这里rest.init实际上并不是跑

相关内容

最新更新