testing angular service internal method calls

假装没事ソ 提交于 2019-12-08 10:10:39

问题


I have the following simple service

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

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

I want to test if the method a is being called when I call method b. My test looks like this:

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();
  })

});

But the tests fail. Relevant plunker is here.

Question is how can I test this kind of interactions?


回答1:


What happens here is that you set on a spy on service.a method, but the internal a (which is called internally by b) is still the same internal method (i.e not the spy), that's why your test fail.

If you really want to do that, the only way is to not call the internal a but the method of your service:

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

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

Here is an update of your plunkr: https://plnkr.co/edit/6FZptdcX9qwyOE6kbgAX

EDIT:

Just some explanation: the service.a method is just a pointer to the internal a method. When you say spyOn(service, 'a'), you are just overwriting the service.a pointer to point to a completely different method (i.e a spy created by jasmine). The internal a method is private and will be never updated, so if you call a() in your internal b method, you just call the original method a not the spy pointed by service.a.




回答2:


I managed to fix this issue with the following code

app.factory('Shoes', function() {
    var module = {
      a:function(){
        return 12;
      },
      b: function(){
        return this.a();
      }
    }
    return module;
});

It seems like your tested module can't just call a "function". It should call the method of the object returned;

Updated Plunker: https://plnkr.co/edit/DeDmdQq3rguO6uGHElW6?p=preview




回答3:


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

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

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

I believe that's because b is not calling the function you are spying on. With factory above test passes.



来源:https://stackoverflow.com/questions/36222079/testing-angular-service-internal-method-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!