如何在业力测试中更改恒定值

tuf*_*uff 4 javascript unit-testing angularjs karma-runner

我有一个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
    });    
});
Run Code Online (Sandbox Code Playgroud)

Kas*_*wau 5

您正在提供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');
});
Run Code Online (Sandbox Code Playgroud)

如果您需要在之间更​​改常量的值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();
  });
}
Run Code Online (Sandbox Code Playgroud)

然后在您的规范中,您将执行以下操作:

it('equals banana', function () {
  setupModule('banana');
  injectItAll();
  expect($scope.propertyBasedOnConstant).to.equal('banana');
});
Run Code Online (Sandbox Code Playgroud)