用sinon存根在角控制器构造中调用的范围方法

Stubbing a scope method invoked in angular controller construction with sinon

本文关键字:调用 范围 方法 存根 sinon 控制器      更新时间:2023-09-26

我有一个控制器,在构建时调用附加到$scope的方法:

angular.module('example', []).controller('exampleCtrl', function($scope) {
    $scope.method = function () { ... };
    $scope.method();
});

我想测试在控制器的构造过程中,这个方法被调用。我使用jasmine作为我的测试框架,使用sinon.js作为我的mock框架。

describe('tests', function() {
    var $scope, $controller;
    beforeEach(inject(function($rootScope, _$controller_) {
        $scope = $rootScope.$new();
        $controller = _$controller_;
    });
    describe('During construction', function() {
        it('should call "method"', function() {
            $controller('exampleCtrl', { $scope: $scope });
            var methodStub = sinon.stub($scope, 'method');
            expect(methodStub.called).toBe(true);
        });
    });
});

这失败了,因为一旦$controller()被调用,它立即调用$scope.method()之前,我能够存根。但是,如果我试图在构造之前存根方法,

it('should call "method"', function() {
    var methodStub = sinon.stub($scope, 'method');
    $controller('exampleCtrl', { $scope: $scope });
    expect(methodStub.called).toBe(true);
});

sinon抛出错误:TypeError: Cannot read property 'restore' of undefined,因为$scope。方法没有定义,因为我没有调用构造函数!

我还尝试直接在$scope(即$scope.method = sinon.stub())上存根方法,但在控制器构造期间会被覆盖。

那么,在构造期间调用的方法是否可能存根?

这是行不通的,因为控制器总是覆盖你的存根。

这更像是一个代码整洁的问题。

首先,控制器不应该包含任何复杂的逻辑。通常它会进行测试,以便模拟依赖项并检查它们是否被正确调用。

其次,首选控制器符号是"controller as"。因此Controller是一个经典的JS类。如果你在原型中定义了方法,你可以模拟/存根它。

但是一般来说,这个要求有点不寻常,可能表明控制器做得太多了。