javascript - 具有隔离范围的单元测试 AngularJS 指令 - 如何获取输出的绑定(bind)?

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

我真的需要关于使用隔离范围测试 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');
                }
             }
        };
    })
;

这是模板 URL 代码:

<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 (由于某种原因绑定(bind) {{ title }} 未渲染)。现在,如果我将 $scope.title 作为属性放在元素上,第二个测试将在渲染工作时通过,但第一个测试失败?我什至将第一个测试更改为

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

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

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

最佳答案

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

当然,因为您使用的是 title: '@'@ 表示您使用静态字符串绑定(bind)。

问题2:

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

如这个DEMO显示,如果我立即在同一函数中检查编译后的 html,我会发现它没有编译。为了向大家展示templateUrl是正确的,稍后会加载,我又添加了一个DEMO使用 console.log对象引用来证明这一点

如果我使用内联模板,如DEMO所示,模板被替换(但未编译)。

问题3:

Angular js 编译函数没有在当前函数中完成,您可能需要使用 $timeout 来安排它到下一个周期。 DEMO

关于javascript - 具有隔离范围的单元测试 AngularJS 指令 - 如何获取输出的绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20972680/

相关文章:

使用 Jenkins 进行 JavaScript 单元测试

javascript - 如何通过 javascript 从 CSS 类获取样式属性 ime-mode?

javascript - Vue.js 2、在css中使用自定义组件标签名?

javascript - Angular2 测试。 Promise 从未在 TestBed.compileComponents 中解决

android - 使用 Android 测试过滤器(@SmallTest、@MediumTest、@LargeTest)进行本地单元测试

javascript - 如何使用 Angular JS 将透明 HTML 表单放在后台滑动图像的顶部

javascript - Kendo UI 网格单元中的工具栏菜单,从哪一行单击了菜单?

javascript - 为什么 angularjs 插件无缘无故地使用 $timeout

JavaScript 触发的 UpdatePanel 未正确更新

javascript - react 组件返回 "TypeError: undefined has no properties"