【问题标题】:How to test directives that use templateUrl and controllers?如何测试使用 templateUrl 和控制器的指令?
【发布时间】:2013-06-20 21:10:20
【问题描述】:

编辑:在提出问题后,我现在正在编辑它以详细说明我的发现。

我的应用是使用指令模块化的。我正在编写我的指令,以便它们 (1) 创建自己的范围 (2) 使用 templateUrl,以及 (3) 在其控制器中执行大部分逻辑和服务器数据获取。

问题是如何使用 Mocha 和 Karma 进行单元测试。

【问题讨论】:

    标签: angularjs angularjs-directive karma-runner


    【解决方案1】:

    为每个指令编写一个测试。由于指令使用了templateUrl,所以我使用了html2js。 html 键应作为模块包含 - 将模板放入 templateCache。

    然后,我编译了指令,并使用 rootScope 运行链接函数。我在获取模板 html 时遇到了问题 - 使用 $digest 解决了。有数据绑定问题,通过理解解决。所有记录在下面。

    代码如下,

    指令:

     angular.module('myApp')
     .directive('productThumb', function(){
        return {
         restrict: 'AE',
         scope: true,
         templateUrl: 'partials/directives/product-thumb.html',
         // controller does most of the work
         controller: ProductThumbController 
    
       }
    }) ;
    
    describe("Unit: Testing Directives", function() {
    var elm, scope, linkFn;
    beforeEach(
      module('ogApp','partials/directives/product-thumb.html') // puts product-thumb.html 
                                                              // into templateCache
    );
    
    
    beforeEach(inject(function($rootScope, $compile) {
        elm = angular.element('<product-thumb></product-thumb>');
        scope = $rootScope;
        linkFn = $compile(elm);
        scope.$digest(); // have to digest to bring html from templateCache
        console.log('post compile',elm.html());// <== the html here still have {{}}
    }));
    
    it('should show a thumb',function() {
        inject(function($controller)  {
            linkFn(scope); // <== this will create a new scope (since our directive creates 
                           // new scope), runs the controller with it, and bind 
                           // the element to that new scope
            scope.$digest();
            console.log('post link',elm.html());// <== the html is bound 
    
            // inject test data (controller sets up an $on handler for addProductData event)
            scope.$broadcast('addProductData',{title:"TEST DISPLAY NAME", 
                                              productId: "123", mainImageUrl: "TEST.JPG"});
            scope.$digest();
            expect(elm.find('H5').text()).to.equal("TEST DISPLAY NAME"); // <=== success 
        });
    });
    

    【讨论】:

    • 嗨,Lior,我只想说,谢谢。我试图测试一个使用 templateUrl(而不是模板)的 angular.js 指令,并且我试图避免碰到实际的模板。我使用了您答案的一个非常相似的变体,唯一的区别是我没有使用 html2js;相反,我注入了 $templateCache 并让它返回一个字符串,这对我来说非常有效。再次感谢您!
    • 我遇到的唯一问题是部分模板所在的位置。你怎么知道要使用哪条路径?
    • 路径是相对于应用程序根目录的,例如主要app.js 所在的位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 2015-12-30
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多