【问题标题】:Unit testing AngularJS Directive with isolated scope - how to get bindings to output?具有隔离范围的单元测试 AngularJS 指令 - 如何将绑定绑定到输出?
【发布时间】:2014-01-07 13:19:04
【问题描述】:

我真的需要有关使用独立作用域测试 AngularJS 指令的建议和指导。

假设我有以下指令(有效):

angular.module('myApp')

    .directive('pageNav', function() {
        return {
            restrict: 'A',
            scope: {
                title: '@'
            },
            transclude: true,
            templateUrl: 'pageNav.html',
            link: function(scope, element, attrs) {
                if (attrs.pageNav == 'translucent') {
                    element.find('nav').addClass('newClass');
                }
             }
        };
    })
;

这是模板网址代码:

<nav class="pageNav">
    <div class="content">
        <h1 ng-if="title">{{ title }}</h1>

        <div class="contentRight" ng-transclude></div>
    </div>
</nav>

现在我有以下测试

describe('Page Nav Directive', function() {

    var $scope,
        element;

    beforeEach(module('myApp'));
    beforeEach(module('pageNav.html'));

    beforeEach(inject(function($compile, $rootScope) {
        $scope = $rootScope;
        $scope.title = "hey hey, my my";
        element = angular.element('<div page-nav></div>');
        // element = angular.element('<div page-nav title="hey hey, my my"></div>');
        $compile(element)($scope);

        $scope.$digest();
    }));

    it('should render the directive', function() {
       // this test will fail if I un-comment the element above
       expect(element.find('div').eq(1).attr('class')).toBe('contentRight');
    });

    it('should render a title', function() {
        // this test will pass if I un-comment the element above
       expect(element.find('h1').eq(0).text()).toBe('hey hey, my my');
    });

})

;

现在我不明白为什么即使我设置了$scope.title(由于某种原因绑定{{ title }} 没有呈现),第二个测试为什么会在第一个元素上失败。现在,如果我将$scope.title 作为属性放在元素上,第二个测试将在渲染工作时通过,但第一个测试失败?我什至将第一个测试更改为

expect(element.scope().find('div').eq(1).attr('class')).toBe('contentRight');

使用时,我将$scope.title 作为属性放在元素上,但这也失败了。

我发现很少或没有关于使用隔离范围测试 AngularJS 指令的良好文档,我正在努力解决问题。对我遇到的问题的任何指导、信息或解释将不胜感激。

【问题讨论】:

  • 您能否为此创建一个 jsffidle。它将帮助我们更快地帮助您
  • 这是一个原始的小提琴...jsfiddle.net/itakesmack/ecfpz
  • 你检查过小提琴的工作原理吗?
  • 我刚刚添加了上面的代码,因为我使用的是业力/茉莉花,我希望有人能解释一下渲染和范围的问题,而不是修改代码。
  • 设置$scope.title(由于某种原因绑定{{ title }}没有呈现)。当然,因为您使用的是title: '@',所以@ 意味着您使用静态字符串进行绑定。

标签: javascript unit-testing angularjs angularjs-directive karma-runner


【解决方案1】:

问题 1: 设置 $scope.title(由于某种原因绑定 {{ title }} 未呈现)

当然,因为您使用的是title: '@'@ 意味着您使用静态字符串绑定。

问题 2:

你正在使用templateUrl,浏览器必须发起ajax请求来加载模板,这意味着该指令的模板还没有加载在当前函数,必须等待 ajax 请求完成 => 结果不可预测。

正如DEMO 所示,如果我立即在同一个函数中检查已编译的 html,我会发现它没有被编译。为了向您展示 templateUrl 是正确的并且稍后会加载,我使用 console.log 添加了一个 DEMOobject reference 来证明它

如果我使用内联 template,就像在这个 DEMO 中一样,模板将被替换(但未编译)。

问题 3:

Angular js 编译函数在当前函数中没有完成,你可能需要使用 $timeout 来安排下一个循环。 DEMO

【讨论】:

  • 谢谢,太好了,请问如果我使用 title: '=' 或 title: '&' 意味着什么 - 我可以提出这是一个单独的问题
  • @Mike Sav:检查我更新的问题编号 3。如果需要将其与范围的属性绑定,则应使用 title: '='
  • 感谢您的帮助,我还有其他使用“=”的测试也不绑定,这就是我问的原因。
猜你喜欢
  • 2014-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 2015-05-14
  • 1970-01-01
相关资源
最近更新 更多