单元测试 Angular 控制器的初始化函数
Unit-testing an Angular Controller's initialization function
我认为我面临的是一个非常简单的场景,但我找不到明确的答案:我有一个控制器,它在创建时会做很多事情,包括一些复杂的事情,所以我创建了一个初始化函数来做。
控制器代码如下所示:
function MyCtrl() {
function init() {
// do stuff
}
var vm = this;
vm.init = init;
vm.init();
}
显然,我想对 init() 进行单元测试,但我找不到这样做的方法:当我在测试中实例化控制器时,init() 是 运行 一次,这很难当我第二次 运行 时正确测试它的副作用。
我正在使用 karma-jasmine 进行测试,通常会这样做:
describe('Controller: MyCtrl', function () {
var myCtrl;
beforeEach(angular.mock.module('myApp'));
beforeEach(inject(function ($controller, $rootScope) {
$scope = $rootScope.$new();
createController = function () {
return $controller('MyCtrl', {$scope: $scope});
};
}));
it('bleh', function() {
myCtrl = createController();
// init has already been run at that point
});
)};
同样,我确信它真的很简单,我只是错过了重点,但我对 Angular 还是很陌生。非常感谢您的帮助!
将 JB Nizet 的回答放在此处而不是评论中。
非常感谢您的回答!
It's a chicken and egg problem: init is called by the constructor, and you need to call the constructor in order to call your init function(s). I still maintain that the fact that you have one or several "private" functions called by the constructor is an implementation detail. What you really want to test is that the constructor does its job. You could simplify that by delegating to service functions (that could be unit tested, and mocked when testing the controller).
我认为我面临的是一个非常简单的场景,但我找不到明确的答案:我有一个控制器,它在创建时会做很多事情,包括一些复杂的事情,所以我创建了一个初始化函数来做。
控制器代码如下所示:
function MyCtrl() {
function init() {
// do stuff
}
var vm = this;
vm.init = init;
vm.init();
}
显然,我想对 init() 进行单元测试,但我找不到这样做的方法:当我在测试中实例化控制器时,init() 是 运行 一次,这很难当我第二次 运行 时正确测试它的副作用。
我正在使用 karma-jasmine 进行测试,通常会这样做:
describe('Controller: MyCtrl', function () {
var myCtrl;
beforeEach(angular.mock.module('myApp'));
beforeEach(inject(function ($controller, $rootScope) {
$scope = $rootScope.$new();
createController = function () {
return $controller('MyCtrl', {$scope: $scope});
};
}));
it('bleh', function() {
myCtrl = createController();
// init has already been run at that point
});
)};
同样,我确信它真的很简单,我只是错过了重点,但我对 Angular 还是很陌生。非常感谢您的帮助!
将 JB Nizet 的回答放在此处而不是评论中。
非常感谢您的回答!
It's a chicken and egg problem: init is called by the constructor, and you need to call the constructor in order to call your init function(s). I still maintain that the fact that you have one or several "private" functions called by the constructor is an implementation detail. What you really want to test is that the constructor does its job. You could simplify that by delegating to service functions (that could be unit tested, and mocked when testing the controller).