我有一个使用$stateParams
的基本控制器。
angular.module('example')
.controller('SampleCtrl', ['$stateParams',
function($stateParams) {
var vm = this;
vm.isSomething = ($stateParams.isSomething === 'true') ? true : false;
}
]);
在我的单元测试中,我需要在一次测试中将$stateParams.isSomething
设置为true,在另一次测试中设置为false。
describe('SampleCtrl Test', function() {
var ctrl, scope, $stateParams;
// set default stateParams
$stateParams = { isSomething: 'false' };
beforeEach(function(){
inject(function($rootScope, $controller){
scope = $rootScope.$new();
ctrl = $controller('SampleCtrl', {
$scope: scope,
$stateParams: $stateParams
});
});
});
describe('when isSomething is false', function() {
it('should be false', function() {
expect(ctrl.isSomething).toBe(false);
});
});
describe('when isSomething is true', function() {
beforeEach(function() {
$stateParams.isSomething = 'true';
});
it('should be true', function() {
// THIS IS FAILING
expect(ctrl.isSomething).toBe(true);
});
});
});
如何针对不同的测试正确模拟$stateParams
的不同状态?
答案 0 :(得分:6)
我认为您需要使用更新的范围对象再次实例化控制器。
您也有一些命名问题,请参阅下面代码中的注释。
describe('SampleCtrl Test', function() {
var ctrl, scope, $stateParams, $controller;
// set default stateParams
// you have called it 'something' in your controller not 'isSomething'
$stateParams = { something: 'false' };
beforeEach(function(){
// load module
module('example');
inject(function($rootScope, _$controller_){
scope = $rootScope.$new();
// angular removes the _'s for you so you can call it $controller
$controller = _$controller_;
ctrl = $controller('SampleCtrl', {
$scope: scope,
$stateParams: $stateParams
});
});
});
describe('when isSomething is false', function() {
it('should be false', function() {
expect(ctrl.isSomething).toBe(false);
});
});
describe('when isSomething is true', function() {
beforeEach(function() {
// you have called it 'something' in your controller not 'isSomething'
$stateParams.something = 'true';
// instantiate a new controller with the updated $stateParams object
ctrl = $controller('SampleCtrl', {
$scope: scope,
$stateParams: $stateParams
});
});
it('should be true', function() {
// THIS IS FAILING
expect(ctrl.isSomething).toBe(true);
});
});
});
答案 1 :(得分:1)
你遇到的问题是describe的beforeEach('当isSomething为true')在之前的describe('SampleCtrl Test')之后评估,即控制器已经实例化当$ stateParams值改变时。正如Matt在他的回答中写道,你需要在改变发生后实例化控制器。
我通常会使用简单的解决方法。由于beforeEach在控制器之后被实例化,我通常会写一个空的it语句,其中错误的stateParams被发送到控制器并忽略那个。对于所有前面的语句,将发生对stateParams更改的更改,然后控制器将使用正确的变量:
describe('when isSomething is true', function() {
beforeEach(function() {
$stateParams.isSomething = 'true';
});
it('should take one iteration to set the state parameter', function() {
// do nothing as the controller will not use the new $stateParams yet
});
it('should be true', function() {
// THIS IS NO LONGER FAILING
expect(ctrl.isSomething).toBe(true);
});
});
虽然不是最美丽的解决方案,但它似乎是最简单的