在$ scope。$ broadcast上使用Jasmnie的spyOn

时间:2017-02-07 13:33:16

标签: angularjs unit-testing jasmine karma-jasmine

我使用jasmine的spyOn函数来尝试确定是否已调用$ scope。$ broadcast。

girlnames.spec.js - 控制器

describe('Girl names controller', function() {
    var vm,
        $scope;

    beforeEach(module('nameStats'));

    beforeEach(inject(function($controller, $rootScope, $q, _$httpBackend_, _namesService_) {
        vm = $controller('girlNames', {
            $scope: $rootScope.$new()
        });

        $scope = $rootScope.$new()

    }));


    it('addPersonManually should trigger $scope.$broadcast', function() {
        spyOn($scope, '$broadcast').and.callThrough()
        vm.addPersonManually(p)
        $scope.$digest();
        expect($scope.$broadcast).toHaveBeenCalled()
    });

});

girlnames.js - 控制器

    "use strict";

    angular.module('nameStats').controller('girlNames', girlNames);

    girlNames.$inject = ['$scope', 'namesService'];

    function girlNames($scope, namesService) {
        var vm = this;

        vm.addPersonManually = addPersonManually;

        function addPersonManually(person) {
            $scope.$broadcast('personSelected', person);

        }
}   

控制台中的输出:

Expected spy $broadcast to have been called.

1 个答案:

答案 0 :(得分:1)

仔细查看实例化控制器的方式

beforeEach(inject(function($controller, $rootScope, $q, _$httpBackend_, _namesService_) {
    vm = $controller('girlNames', {
        $scope: $rootScope.$new()
    });

    $scope = $rootScope.$new();
}));

您注入一个范围实例并使用完全不同的范围进行测试。

您的代码应如下所示

beforeEach(inject(function($controller, $rootScope) {
    $scope = $rootScope.$new();

    vm = $controller('girlNames', {
        $scope: $scope
    });
}));

高级提示

考虑在测试中删除局部变量。 Karma保留对所有测试套件的引用,直到它们都完成运行,从而导致巨大的内存消耗。如果你有足够的测试,它甚至可能导致进程失败(在我们的例子中它只有几千)。 Useful article

使用this代替

beforeEach(inject(function($controller, $rootScope) {
    this.$scope = $rootScope.$new();

    this.ctrl = $controller('girlNames', {
        $scope: $scope
    });
}));

it('addPersonManually should trigger $scope.$broadcast', function() {
    spyOn(this.$scope, '$broadcast').and.callThrough()
    this.ctrl.addPersonManually(p)
    this.$scope.$digest();
    expect(this.$scope.$broadcast).toHaveBeenCalled()
});