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

后端 未结 3 1575
耶瑟儿~
耶瑟儿~ 2021-02-20 03:57

I have a method in a service that uses underscore\'s debounce.

Inside that method is a call to a method on a different service. I\'m trying to test that the different s

相关标签:
3条回答
  • 2021-02-20 04:27

    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();
      });
    });
    
    0 讨论(0)
  • 2021-02-20 04:33

    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)

    0 讨论(0)
  • 2021-02-20 04:40

    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.

    0 讨论(0)
提交回复
热议问题