如何在 Karma 测试中更改常量值
How to change constant value in a Karma test
我有一个 Angular 指令,它根据注入常量的值设置一些 $scope
属性 的值。我想测试这个值是否从常量正确初始化,所以我想在单个 it
块中更改常量的值。 (最好在一个内,但在多个块之间更改值也可以)
这可能吗,我该怎么做?
简化示例:
//////// directive ////////
angular.module('myApp.directives', [])
.constant('THE_CONSTANT', 'hello world')
.directive('myDirective', ['THE_CONSTANT', function (THE_CONSTANT) {
return {
restrict: 'E',
link: function ($scope) {
$scope.propertyBasedOnConstant = THE_CONSTANT;
}
};
}]);
//////// test ////////
describe('myDirective', function () {
var $element, $scope;
beforeEach(module('myApp.directives'));
beforeEach(module(function ($provide) {
$provide.constant('THE_CONSTANT', 'foo');
}));
beforeEach(inject(function ($rootScope, $compile) {
$scope = $rootScope;
$element = angular.element('<my-directive></my-directive>');
$compile($element)($scope);
$scope.$digest();
}));
afterEach(function () {
$scope.$destroy();
$element.remove();
});
it("should correctly reflect the constant's value", function() {
expect( $scope.propertyBasedOnConstant ).to.equal('foo');
// now I want to change the constant's value and re-initialize the directive
});
});
根据定义,常量是具有无法更改的关联值的标识符。为什么不注入常量本身并在您的期望范围内使用它,而不是更改常量值。
describe('myDirective', function () {
var $element, $scope,
THE_CONSTANT;
beforeEach(module('myApp.directives'));
beforeEach(module(function (_THE_CONSTANT_) {
THE_CONSTANT = _THE_CONSTANT_;
}));
beforeEach(inject(function ($rootScope, $compile) {
$scope = $rootScope;
$element = angular.element('<my-directive></my-directive>');
$compile($element)($scope);
$scope.$digest();
}));
afterEach(function () {
$scope.$destroy();
$element.remove();
});
it("should correctly reflect the constant's value", function() {
expect( $scope.propertyBasedOnConstant ).to.equal(THE_CONSTANT);
});
});
您正在将 constant
提供给 undefined
模块。
将您的 beforeEach 块更改为类似这样的内容,它 应该可以正常工作™:
var $scope, $element, MOCKED_CONSTANT;
beforeEach(function () {
MOCKED_CONSTANT = 'foo';
module('myApp.directives', function ($provide) {
$provide.constant('THE_CONSTANT', MOCKED_CONSTANT);
});
inject(function ($rootScope, $compile) {
$scope = $rootScope.$new(); // Don't forget to call .$new()!
var template = angular.element('<my-directive></my-directive');
$element = $compile(template)($scope); // Store the reference to the compiled element, not the raw string.
$scope.$digest();
});
});
it("should correctly reflect the constant's value", function() {
expect( $scope.propertyBasedOnConstant ).to.equal(MOCKED_CONSTANT);
// expect( $scope.propertyBasedOnConstant ).to.equal('foo');
});
如果您需要更改 it
之间的常量值,我会将对 module
的调用以及 inject
的调用提取到辅助函数中。如:
function setupModule (constant) {
module('myApp.directives', function ($provide) {
$provide.constant('THE_CONSTANT', constant);
});
}
function injectItAll () {
inject(function ($rootScope, $compile) {
$scope = $rootScope.$new(); // Don't forget to call .$new()!
var template = angular.element('<my-directive></my-directive');
$element = $compile(template)($scope); // Store the reference to the compiled element, not the raw string.
$scope.$digest();
});
}
然后在你的规范中你会做:
it('equals banana', function () {
setupModule('banana');
injectItAll();
expect($scope.propertyBasedOnConstant).to.equal('banana');
});
我有一个 Angular 指令,它根据注入常量的值设置一些 $scope
属性 的值。我想测试这个值是否从常量正确初始化,所以我想在单个 it
块中更改常量的值。 (最好在一个内,但在多个块之间更改值也可以)
这可能吗,我该怎么做?
简化示例:
//////// directive ////////
angular.module('myApp.directives', [])
.constant('THE_CONSTANT', 'hello world')
.directive('myDirective', ['THE_CONSTANT', function (THE_CONSTANT) {
return {
restrict: 'E',
link: function ($scope) {
$scope.propertyBasedOnConstant = THE_CONSTANT;
}
};
}]);
//////// test ////////
describe('myDirective', function () {
var $element, $scope;
beforeEach(module('myApp.directives'));
beforeEach(module(function ($provide) {
$provide.constant('THE_CONSTANT', 'foo');
}));
beforeEach(inject(function ($rootScope, $compile) {
$scope = $rootScope;
$element = angular.element('<my-directive></my-directive>');
$compile($element)($scope);
$scope.$digest();
}));
afterEach(function () {
$scope.$destroy();
$element.remove();
});
it("should correctly reflect the constant's value", function() {
expect( $scope.propertyBasedOnConstant ).to.equal('foo');
// now I want to change the constant's value and re-initialize the directive
});
});
根据定义,常量是具有无法更改的关联值的标识符。为什么不注入常量本身并在您的期望范围内使用它,而不是更改常量值。
describe('myDirective', function () {
var $element, $scope,
THE_CONSTANT;
beforeEach(module('myApp.directives'));
beforeEach(module(function (_THE_CONSTANT_) {
THE_CONSTANT = _THE_CONSTANT_;
}));
beforeEach(inject(function ($rootScope, $compile) {
$scope = $rootScope;
$element = angular.element('<my-directive></my-directive>');
$compile($element)($scope);
$scope.$digest();
}));
afterEach(function () {
$scope.$destroy();
$element.remove();
});
it("should correctly reflect the constant's value", function() {
expect( $scope.propertyBasedOnConstant ).to.equal(THE_CONSTANT);
});
});
您正在将 constant
提供给 undefined
模块。
将您的 beforeEach 块更改为类似这样的内容,它 应该可以正常工作™:
var $scope, $element, MOCKED_CONSTANT;
beforeEach(function () {
MOCKED_CONSTANT = 'foo';
module('myApp.directives', function ($provide) {
$provide.constant('THE_CONSTANT', MOCKED_CONSTANT);
});
inject(function ($rootScope, $compile) {
$scope = $rootScope.$new(); // Don't forget to call .$new()!
var template = angular.element('<my-directive></my-directive');
$element = $compile(template)($scope); // Store the reference to the compiled element, not the raw string.
$scope.$digest();
});
});
it("should correctly reflect the constant's value", function() {
expect( $scope.propertyBasedOnConstant ).to.equal(MOCKED_CONSTANT);
// expect( $scope.propertyBasedOnConstant ).to.equal('foo');
});
如果您需要更改 it
之间的常量值,我会将对 module
的调用以及 inject
的调用提取到辅助函数中。如:
function setupModule (constant) {
module('myApp.directives', function ($provide) {
$provide.constant('THE_CONSTANT', constant);
});
}
function injectItAll () {
inject(function ($rootScope, $compile) {
$scope = $rootScope.$new(); // Don't forget to call .$new()!
var template = angular.element('<my-directive></my-directive');
$element = $compile(template)($scope); // Store the reference to the compiled element, not the raw string.
$scope.$digest();
});
}
然后在你的规范中你会做:
it('equals banana', function () {
setupModule('banana');
injectItAll();
expect($scope.propertyBasedOnConstant).to.equal('banana');
});