javascript - Jasmine:在spyOn之后调用带有函数引用的真实函数

标签 javascript angularjs unit-testing jasmine spy

我有一个 Angular 服务。在这个服务中,我有一个带有函数的对象,它引用服务上的另一个函数。 (代码如下)

我想使用 Jasmine (1.3) 来监视我的服务函数,以验证当对象的函数被调用时,它实际上调用了真正的函数。

我的问题:调用spyOn后,真正的函数仍在调用。

FooService.js

angular.module('foo').service("FooService", function() {
     var self = this;

     this.fooFunction = function() {
         console.log("Foo function is being called");
     }

     this.bar = {
         barFunction : self.fooFunction
     }
});

FooService-spec.js

describe("Testing FooService", function() {
     var service;

     beforeEach(inject(function(_FooService_) {
         service = _FooService_;
     }));

     describe("Test bar object", function() {
        it("should call fooFunction when bar.barFunction is called", function() {
             spyOn(service, "fooFunction");
             service.bar.barFunction();
             expect(service.fooFunction).toHaveBeenCalled();
         });
     });
 });

我发现,如果我将 FooServce.js 更改为以下内容,这一切都会起作用:

FooService - 工作

angular.module('foo').service("FooService", function() {
     var self = this;

     this.fooFunction = function() {
         console.log("Real function is being called");
     }

     this.bar = {
         barFunction : function() {
             return self.fooFunction();
         }
     }
 });

在第一个示例中我无法理解 JavaScript/Angular/Jasmine 的哪一部分?

最佳答案

spyOn 通过将对象属性的值替换为不同的值来进行操作。当你执行 spyOn(service, "fooFunction"); 你正在做类似的事情

var realFunc = service.fooFunction;
service.fooFunction = function() {
    doSpyStuff();
    return realFunc.apply(this, arguments);
}

请注意,这不会修改值 service.fooFunction。它实际上修改了 service —— 也就是说,service 的属性之一现在是一个完全不同的函数。此替换只会影响 servicefooFunction 属性。如果您没有访问 service 的属性,那么您肯定不会调用 spy 功能。

所以让我们将这些知识应用到您的案例中。在您的测试中,您正在访问 service.bar 的属性。虽然 service.bar.barFunctionservice.fooFunction 最初是相同的值,但 service 拥有其 fooFunction 属性被 spy 取代,而(非常重要的是)service.bar 的任何属性都没有被 spyOn 改变。当您调用 service.bar.barFunction() 时,您直接调用真正的函数,并且与 servicefooFunction< 上的 spy 没有任何连接 属性。

相比之下,当你执行 barFunction: function() { return self.fooFunction(); 时} 作为一个匿名函数,您实际上正在访问 service 上的 spy 属性值,因为这里 self 恰好是 service,因此 self.fooFunctionservice.fooFunction,它是保存 spy 替换值的属性。

关于javascript - Jasmine:在spyOn之后调用带有函数引用的真实函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38252144/

相关文章:

javascript - 在性能方面,在一个页面上显示 1000 张图像的最佳方法是什么?

javascript - d3.csv修改输入数据

QtWebKit 中的 JavaScript 和异步方法

javascript - Sinon单元测试MySQL连接

database - 需要上下文的 Android 单元测试

ios - 测试因 faSTLane 错误而失败

javascript - 如何使用 jQuery 获取另一个页面上的 cookie 值?

javascript - 正则表达式 从字符串中提取模板标签 {{..}}

javascript - 当我调用 onClick 函数时如何隐藏删除按钮

angularjs - 在 angularjs 中为多个 Controller 路由?