如何在指令中将attrs数组设置为undefined

时间:2015-06-05 15:40:55

标签: javascript angularjs jasmine

我想在单元测试中将attrs设置为undefined,我尝试了几种方法,但未将其设置为undefined。以下是我的指示:

angular.module('myApp').directive('someElement', function () {

var directive = {};

directive.restrict = 'E';
directive.replace = true;
directive.transclude = true;

directive.templateUrl = function (element, attrs) {
  var template = '';
  if(attrs) { // would like to invoke this in unit test and set it to `undefined`
    //do something
  }
  return template;
};

directive.scope = {...};

directive.compile = function () {
    //do something
return directive;
});

这是一个片段,假设编译指令并触发$digest周期。这是我在测试中得到的:

it('should set attrs to undefined', function () {
    .....
    attrs = {};
    scope.$apply();
    expect(attrs).toBeUndefined(); // I want this to pass!!
});

1 个答案:

答案 0 :(得分:0)

可以从测试中获取原始指令工厂并在编译之前对其进行修改甚至对其方法进行单元测试,但我不确定这种测试指令的方法是否正确。 If you take a look at the source code,您可以看到angular将每个指令注册为带有'Directive'后缀的工厂。知道这一点,你可以在测试中注入你的指令工厂:

var directiveFactory;

beforeEach(inject(function ($injector) {
    // considering that you directive is called 'myEl'
    directiveFactory = $injector.get('myElDirective')[0];
}));

这里应该使用[0],因为工厂是以数组形式返回的 - 这就是angular处理指令的方式,它有一个选项multiElement: true(如果你启用了这个选项,那么也许这个技巧不行。)

因此,变量directiveFactory现在拥有一个实际的工厂,因此可以替换原始templateUrl并使用未定义的attrs进行伪造:

it('should do something when attrs are undefined', function () {

    var template = '<my-el></my-el>';

    // backup original function
    var originalTemplateUrl = directiveFactory.templateUrl;

    // replace with fake one
    directiveFactory.templateUrl = function (element, attrs) {
        // call original function with undefined attrs
        return originalTemplateUrl(element, undefined);
    };

   var element = $compile(template)($scope);
   $scope.$digest();

   // expect whatever
});

现在,您可以检查对指令原始templateUrl的调用,并发现attrsundefined

See the plunker