How do I test angularjs directive to spy on the function call?

后端 未结 2 802
轮回少年
轮回少年 2021-02-08 04:03

Code below executes but complains about element.popover not being invoked. I can\'t seem to figure out what the issue is.

Thanks for help in advance.

dir

2条回答
  •  迷失自我
    2021-02-08 05:04

    Update:

    I wasn't able to solve your specific problem. Mostly because I couldn't get angular-seed going/it was taking forever, but I thought I'd make my answer more complete.

    There are 2 ways to solve this problem in general:

    1. Spy on a function other than the one being triggered by some event/intermediary
    2. Spy on the prototype of the function before the object is created. In other words: spyOn(MyObjectNamespace.Class.prototype, 'functionToSpyOn')

    Afterwards just restore and you should be fine.


    I am only vaguely familiar with angular, but have experienced similar problems.

    Solution 1

    You can just separate out the function rather than specifying it anonymously. This helps test your functionality specifically and avoid all the angular stuff.

    Solution 2

    Sometimes with frameworks this isn't possible. The main problem here is that your spy is attaching itself too late and the reference is lost or gets overridden.

    Test:

    describe('directives', function() {
        beforeEach(module('directives'));
        describe('popOver', function() {
        var $scope, compile, location,  $httpBackend, elm;
    
        beforeEach(inject(function($rootScope, $compile, _$httpBackend_) {
            $scope = $rootScope.$new();
            compile = $compile;
            $httpBackend = _$httpBackend_;
            elm = angular.element(' ');
            compile(elm)($scope);
    
        }));
    
        it('should call element.popover()', function() {
            var popoverFunction = $.fn.popover;
            $httpBackend.expectGET('someurl/testChatId.json').
                respond([ {firstName: 'test', lastName: 'user'}]);
    
            spyOn($.fn, 'popover').andCallThrough();
    
            elm.trigger('mouseover');
            $httpBackend.flush();
    
            expect($.fn.popover).toHaveBeenCalled();
            //restore popover, use sinon's restore fn instead here
            $.fn.popover = popoverFunction
        });
      });
    });
    

    You can use Sinon with Jasmine. Sinon has a spy.restore function that gets rid of the first and last line for you. In my own tests I've placed the first line and the spy creation in a beforeEach and the restore in an afterEach.

提交回复
热议问题