Функция просмотра слушателя spyOn не работает

Когда я пытаюсь шпионить за функцией слушателя $scope.$watch, это похоже на то, что я никогда не вызываю spyOn

http://jsfiddle.net/b8LoLwLb/1/

Мой контроллер

angular.module('angularApp')
    .controller('MainCtrl', function ($scope) {
        $scope.name = '';

        this.changeName = function () {
            console.log('the name has change to ' + $scope.name);
        };

        $scope.$watch('name', this.changeName);
    });

Мой тест

describe('Controller: MainCtrl', function () {

    // load the controller's module
    beforeEach(module('angularApp'));

    var MainCtrl,
        scope;

    // Initialize the controller and a mock scope
    beforeEach(inject(function ($controller, $rootScope) {
        scope = $rootScope.$new();
        MainCtrl = $controller('MainCtrl', {
            $scope: scope
        });
    }));

    it('should check if watcher was triggered', function () {
        // Spy the listener funtion
        spyOn(MainCtrl, 'changeName');

        // Change the watched property
        scope.name = 'facu';

        // Digest to trigger the watcher.
        scope.$digest();

        // Expect the function to have been called
        expect(MainCtrl.changeName).toHaveBeenCalled();
    });
});

Проблема в том, что вместо того, чтобы отслеживать функцию, тест выполняет ее и печатает журнал консоли.

Я использую угловой 1.4


person Facundo Pedrazzini    schedule 11.06.2015    source источник
comment
проверьте скрипт js, функция прослушивания часов не запускается при создании экземпляра контроллера.   -  person Facundo Pedrazzini    schedule 11.06.2015


Ответы (1)


Это ожидаемое поведение, оно не имеет ничего общего с jasmine или angular, а связано со ссылкой на функцию, хранимую свойством. Когда вы выполняете $scope.$watch('name', this.changeName) при создании экземпляра контроллера, ссылка на функцию, удерживаемая this.changeName(в то время), устанавливается для отслеживания. Даже если вы отслеживаете функцию экземпляра контроллера (позже), ссылка на функцию, хранящаяся в свойстве changeName экземпляра контроллера, изменяется только (на функцию-оболочку, созданную jasmine для отслеживания вызова), но не наблюдателя, поскольку он по-прежнему использует исходную ссылку на функцию. Поэтому, когда часы выполняются, они просто запускают фактическую ссылку на функцию, а не ссылку на шпионскую функцию, которую вы позже установили в свойстве changeName.

Вместо этого, если вы сделаете это в своем контроллере:

   var vm = this;
   $scope.$watch('name', function(){
       vm.changeName();
   });

Вы увидите, что ваш тест проходит.

person PSL    schedule 11.06.2015