【问题标题】:Unit test failing when directive is an Attribute当指令是属性时单元测试失败
【发布时间】:2015-10-14 22:59:46
【问题描述】:

我有一个声明为属性的指令:

app.directive('myDirective', function() {
    return {
        restrict: 'A',
        replace: true,
        transclude: true,
        scope: {
            data: "="
        },
        template:
            '<p class="my-paragrapgh">' +
                '<label>Hello</label>' +
            '</p>'
    }
});

我有一个单元测试失败了:

describe('myDirective test', function () {
var scope, compile, element;

beforeEach(module('myModule'));

beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();

    element = angular.element("<div my-directive></div>");
    $compile(element);
    scope.$digest();
}));

it('should have a my-paragrapgh class', function () {
    expect($(element).find('p')[0]).toHaveClass('my-paragrapgh');
});

});

但是,如果我将我的指令转换为元素,并删除替换和转入:

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        //replace: true,
        //transclude: true,
        scope: {
            data: "="
        },
        template:
            '<p class="my-paragrapgh">' +
                '<label>Hello</label>' +
            '</p>'
    }
});

我的单元测试通过了:

describe('myDirective test', function () {
var scope, compile, element;

beforeEach(module('myModule'));

beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();

    element = angular.element("<my-directive></my-directive>");
    $compile(element);
    scope.$digest();
}));

it('should have a my-paragrapgh class', function () {
    expect($(element).find('p')[0]).toHaveClass('my-paragrapgh');
});

});

如何成功测试声明为属性的指令?我正在使用 Karma、Jasmine 和 PhantomJS

【问题讨论】:

    标签: angularjs jasmine phantomjs karma-jasmine angular-directive


    【解决方案1】:

    当您有transclude: true 时,您需要在模板中的某处有一个ng-transclude,以便angular 知道在哪里注入您的HTML。试试:

    app.directive('myDirective', function() {
        return {
            restrict: 'A',
            replace: true,
            transclude: true,
    
            scope: {
                data: "="
            },
    
            template:
                '<div ng-transclude><p class="my-paragrapgh">' +
                    '<label>Hello</label>' +
                '</p></div>'
        }
    });
    

    更新

    看起来是 replace 选项可能导致问题。

    app.directive('myDirective', function() {
        return {
            restrict: 'A',
    
            scope: {
                data: "="
            },
    
            template:
                '<p class="my-paragrapgh">' +
                    '<label>Hello</label>' +
                '</p>'
        }
    });
    

    replace: true 你的内部 HTML 是:

    失败

    <label>Hello</label>
    

    replace undefined 你有

    通过

    <p class="my-paragrapgh"><label>Hello</label></p>
    

    【讨论】:

    • 这是否会对我在测试中声明元素的方式产生影响:element = angular.element("
      ");
    • 加了上面,用ng-translcude,测试通过,用ng-transclude,失败
    • 不知道你在追求什么。这就是我所拥有的plnkr.co/edit/z9pj9unddB5zsJZZhqIW?p=preview
    • 我之后是 transclude 拼写错误,在这两个例子中,你都建议 translcude
    • transLCude 而非 transCLude
    【解决方案2】:

    适用于replacetransclude,即使没有ng-trasclude

    angular.module('myModule', [])
      .directive('myDirective', function() {
        return {
          restrict: 'A',
          replace: true,
          transclude: true,
          scope: {
            data: "="
          },
          template: '<p class="my-paragrapgh">' +
            '<label>Hello</label>' +
            '</p>'
        }
      });
    
    describe('myDirective test', function() {
      var scope, compile, element;
    
      // Even we can introduce our Jasmine custom matcher
      beforeEach(function() {
        jasmine.addMatchers({
          toHaveCSSClass: function(util, customEqualityTesters) {
            return {
              compare: function(actual, expected) {
                debugger;
                var result = {};
                result.pass = util.equals(actual.hasClass(expected), true, customEqualityTesters);
                if (result.pass) {
                  result.message = "Expected " + actual + " to not have CSS class '" + expected + "'";
                } else {
                  result.message = "Expected " + actual + " to have CSS class '" + expected + "'";
                }
                return result;
              }
            }
          }
        });
      });
    
      beforeEach(module('myModule'));
    
    
      beforeEach(inject(function($rootScope, $compile) {
        scope = $rootScope.$new();
        element = angular.element("<div my-directive></div>");
        $compile(element);
        scope.$digest();
      }));
    
      it('has a my-paragrapgh class', function() {
        expect(element.hasClass('my-paragrapgh')).toBeTruthy();
      });
      
      it('has a my-paragrapgh class - tested by custom matcher', function() {
        expect(element).toHaveCSSClass('my-paragrapgh')
      });
    
    });
    <link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />
    <script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-mocks.js"></script>

    【讨论】:

      猜你喜欢
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 2023-04-04
      • 2012-07-12
      • 2017-11-22
      相关资源
      最近更新 更多