Javascript 使用sinon在angular controller构造中调用的范围方法存根

Javascript 使用sinon在angular controller构造中调用的范围方法存根,javascript,angularjs,unit-testing,jasmine,sinon,Javascript,Angularjs,Unit Testing,Jasmine,Sinon,我有一个控制器,它在构造时调用连接到$scope的方法: angular.module('example', []).controller('exampleCtrl', function($scope) { $scope.method = function () { ... }; $scope.method(); }); 我想测试一下,在构建控制器的过程中,调用这个方法。我使用jasmine作为测试框架,使用sinon.js作为模拟框架 describe('tests', f

我有一个控制器,它在构造时调用连接到
$scope
的方法:

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

    $scope.method();
});
我想测试一下,在构建控制器的过程中,调用这个方法。我使用jasmine作为测试框架,使用sinon.js作为模拟框架

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:无法读取未定义的
的属性“restore”,因为$scope.method未定义,因为我尚未调用构造函数

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


那个么,有可能在构造过程中对调用的方法进行存根吗?

它不会工作,因为控制器总是覆盖存根

这更像是一个干净代码的问题

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

其次,首选控制器符号是“”。因此,Controller是一个经典的JS类。如果在原型中定义方法,则可以对其进行模拟/存根


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

当我面临这种情况时,我通常会将相关代码转移到服务中。这样,可以在创建控制器之前将其存根。我认为代码最终会变得更干净/更易于测试。同意@Sunil。您还可以测试方法的预期行为,而不是对它的特定调用。如果该方法曾经被重构为部分、重命名等,那么它仍然可以工作,这是一个很好的副作用。