测试角度服务内部方法调用

时间:2016-03-25 14:41:31

标签: javascript angularjs unit-testing jasmine

我有以下简单的服务

app.factory('Shoes', function() {
    function a() {return 12;}
    function b() {return a();}

    return {
      a: a,
      b: b
    }
  })

我想测试在调用方法a时是否正在调用方法b。我的测试看起来像这样:

describe('Testing a Shoes service', function() {
  var service;

  beforeEach(module('plunker'));

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

  it('.b should call .a', function() {
    spyOn(service, 'a');
    service.b();
    expect(service.a).toHaveBeenCalled();
  })

});

但测试失败了。相关的plunker是here

问题是如何测试这种互动?

3 个答案:

答案 0 :(得分:3)

这里发生的是您在service.a方法上设置间谍,但内部a(由b内部调用)仍然是相同的内部方法(即不间谍),这就是你的测试失败的原因。

如果您真的想这样做,唯一的方法是不要调用内部a,而是调用您的服务方法:

app.factory('Shoes', function() {
    return {
        a: function a() {
            return 12;
        },

        b: function b() {
            return this.a();
        }
    };
});

以下是您的plunkr的更新:https://plnkr.co/edit/6FZptdcX9qwyOE6kbgAX

编辑:

只是一些解释:service.a方法只是指向内部a方法的指针。当你说spyOn(service, 'a')时,你只是覆盖service.a指针指向一个完全不同的方法(即由jasmine创建的间谍)。内部a方法是私有的,永远不会更新,因此如果您在内部a()方法中调用b,则只需调用原始方法a而不是间谍指向service.a

答案 1 :(得分:0)

我设法通过以下代码解决了这个问题

{{1}}

看起来您的测试模块不能只调用“功能”。它应该调用返回的对象的方法;

更新了Plunker:https://plnkr.co/edit/DeDmdQq3rguO6uGHElW6?p=preview

答案 2 :(得分:0)

app.factory('Shoes', function() {

var self = {
  a: function() {return 12;},
  b: function() {return this.a();}
}

return {
  a: self.a,
  b: self.b
}
})

我相信那是因为b没有调用你正在监视的功能。有工厂以上测试通行证。