Testing a debounced function in AngularJS with Jasmine never calls the function

♀尐吖头ヾ 提交于 2019-12-04 01:32:26
Wawy

You just need to mock lodash debounce method:

describe('Whoa', function(){
  var $injector, whoa, herp;

  beforeEach(function(){
    module('derp');
    spyOn(_, 'debounce').and.callFake(function(cb) { return function() { cb(); } });
    inject(function(_$injector_){
      var Whoa;
      $injector = _$injector_;
      Whoa = $injector.get('Whoa');
      herp = $injector.get('herp');
      whoa = new Whoa();
    });
  });

  beforeEach(function(){
    spyOn(herp, 'aMethod').andCallThrough();
  });

  it('has a method getMind, that calls herp.aMethod', function(){
    whoa.getMind();
    expect(herp.aMethod).toHaveBeenCalled();
  });
});

Angular $timeout has advantage in tests because it is mocked in tests to be synchronous. The one won't have this advantage when third-party asynchronous tools one used. In general asynchronous specs will look like that:

var maxDelay = 500;

  ...
  it('has a method getMind, that calls herp.aMethod', function (done){
    whoa.getMind();
    setTimeout(function () {
      expect(herp.aMethod).toHaveBeenCalled();
      done();
    }, maxDelay);
  });

Since Underscore debounce doesn't offer flush functionality (while the recent version of Lodash debounce does), asynchronous testing is the best option available.

My debounced function took arguments so I mocked _.debounce like this

spyOn(_, 'debounce').and.callFake(function(cb) {return cb});

(slight modification on @Wawy's answer)

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