在不同条件下测试 angular 控制器初始化
Testing angular controller initialisation with different conditions
我有一个依赖于服务的控制器,并且作为其初始化的一部分调用服务上的函数。这是一个人为的例子:
describe('tests', function() {
var _scope, service, serviceValue = 'value';
beforeEach(module('app'));
beforeEach(inject(['$rootScope','$controller', function($rootScope, $controller) {
_scope = $rootScope.$new();
service = {
get: function(key) {
return serviceValue;
}
};
$controller('myController', {
'$scope': _scope,
'service': service
});
}]));
describe('initialisation', function() {
describe('key exists', function() {
it('should find the key', function() {
expect(_scope.message).toBe('found the key');
});
});
describe('key does not exist', function() {
beforeEach(function() {
serviceValue = undefined;
});
it('should not find the key', function() {
expect(_scope.message).toBe('did not find the key');
});
});
});
});
angular.module('app').controller('myController', ['$scope','service',
function($scope, service) {
if(service.get('key') === 'value') {
$scope.message = 'found the key';
} else {
$scope.message = 'did not find the key';
}
});
当键不存在时的测试失败,因为控制器初始化在第一个 beforeEach 中有 运行,在下一个 beforeEach 运行s 之前更改服务 return 值.
我可以通过在 'key does not exist' 测试的 beforeEach 中重新创建整个控制器来解决这个问题,但这对我来说似乎是错误的,因为它会为测试初始化控制器两次。有没有办法让每次测试的控制器初始化为 运行,但在所有其他 beforeEach 函数都有 运行 之后。
这是初始化控制器的正确方法吗?我是否遗漏了 jasmine 的某些功能?
为每个测试创建控制器是推荐的方法,尤其是当您有初始化逻辑时。
不过,我会使用 Jasmine 的 spyOn
来设置服务 return 并跟踪对其调用的内容,而不是修改模拟或真实服务的内部值。
注入真正的服务并将其保存在一个变量中,并定义一个创建控制器的函数:
describe('tests', function() {
var $scope, createController, service;
beforeEach(function() {
module('app');
inject(function($rootScope, $controller, _service_) {
$scope = $rootScope.$new();
service = _service_;
createController = function() {
$controller('myController', {
'$scope': $scope,
'service': service
});
};
});
});
对于每个测试,使用 spyOn
拦截对服务的调用并决定它应该做什么 return,然后创建控制器:
describe('initialisation', function() {
it('should find the key', function() {
spyOn(service, 'get').and.returnValue('value');
createController();
expect($scope.message).toBe('found the key');
});
it('should not find the key', function() {
spyOn(service, 'get').and.returnValue(undefined);
createController();
expect($scope.message).toBe('did not find the key');
});
});
演示: http://plnkr.co/edit/BMniTis1RbOR0h5O4kZi?p=preview
由于 spyOn
设置了跟踪,您现在还可以确保服务仅在控制器初始化时被调用一次:
spyOn(service, 'get').and.returnValue('value');
expect(service.get.calls.count()).toEqual(0);
createController();
expect(service.get.calls.count()).toEqual(1);
注意:以上示例使用 Jasmine 2.0。旧版本的语法必须稍作修改。
我有一个依赖于服务的控制器,并且作为其初始化的一部分调用服务上的函数。这是一个人为的例子:
describe('tests', function() {
var _scope, service, serviceValue = 'value';
beforeEach(module('app'));
beforeEach(inject(['$rootScope','$controller', function($rootScope, $controller) {
_scope = $rootScope.$new();
service = {
get: function(key) {
return serviceValue;
}
};
$controller('myController', {
'$scope': _scope,
'service': service
});
}]));
describe('initialisation', function() {
describe('key exists', function() {
it('should find the key', function() {
expect(_scope.message).toBe('found the key');
});
});
describe('key does not exist', function() {
beforeEach(function() {
serviceValue = undefined;
});
it('should not find the key', function() {
expect(_scope.message).toBe('did not find the key');
});
});
});
});
angular.module('app').controller('myController', ['$scope','service',
function($scope, service) {
if(service.get('key') === 'value') {
$scope.message = 'found the key';
} else {
$scope.message = 'did not find the key';
}
});
当键不存在时的测试失败,因为控制器初始化在第一个 beforeEach 中有 运行,在下一个 beforeEach 运行s 之前更改服务 return 值.
我可以通过在 'key does not exist' 测试的 beforeEach 中重新创建整个控制器来解决这个问题,但这对我来说似乎是错误的,因为它会为测试初始化控制器两次。有没有办法让每次测试的控制器初始化为 运行,但在所有其他 beforeEach 函数都有 运行 之后。
这是初始化控制器的正确方法吗?我是否遗漏了 jasmine 的某些功能?
为每个测试创建控制器是推荐的方法,尤其是当您有初始化逻辑时。
不过,我会使用 Jasmine 的 spyOn
来设置服务 return 并跟踪对其调用的内容,而不是修改模拟或真实服务的内部值。
注入真正的服务并将其保存在一个变量中,并定义一个创建控制器的函数:
describe('tests', function() {
var $scope, createController, service;
beforeEach(function() {
module('app');
inject(function($rootScope, $controller, _service_) {
$scope = $rootScope.$new();
service = _service_;
createController = function() {
$controller('myController', {
'$scope': $scope,
'service': service
});
};
});
});
对于每个测试,使用 spyOn
拦截对服务的调用并决定它应该做什么 return,然后创建控制器:
describe('initialisation', function() {
it('should find the key', function() {
spyOn(service, 'get').and.returnValue('value');
createController();
expect($scope.message).toBe('found the key');
});
it('should not find the key', function() {
spyOn(service, 'get').and.returnValue(undefined);
createController();
expect($scope.message).toBe('did not find the key');
});
});
演示: http://plnkr.co/edit/BMniTis1RbOR0h5O4kZi?p=preview
由于 spyOn
设置了跟踪,您现在还可以确保服务仅在控制器初始化时被调用一次:
spyOn(service, 'get').and.returnValue('value');
expect(service.get.calls.count()).toEqual(0);
createController();
expect(service.get.calls.count()).toEqual(1);
注意:以上示例使用 Jasmine 2.0。旧版本的语法必须稍作修改。