代码之家  ›  专栏  ›  技术社区  ›  Rhushikesh

如何在angularjs中测试指令是否加载

  •  0
  • Rhushikesh  · 技术社区  · 9 年前

    .directive("loadDirective", function($compile, $timeout) {
            return {
                restrict: 'E',
                scope: {
                    Dtype: '=type',
                    subType: '@',
                    data: "=data"
                },
                link: function(scope, element) {
                    scope.$watch('Dtype', function() {
                        $timeout(function() {
                            var generatedTemplate = '<div ' + scope.Dtype + (scope.subType ? '-' + scope.subType + '-directive' : '-directive') + ' data="data" >dd</div>';
                            element.empty().append($compile(generatedTemplate)(scope));
                        })
                    })
                },
            };
        })
    

    .directive("dailyIntervalDirective", function() {
            return {
                scope: {
                    data: '='
                },
                restrict: 'A',
                templateUrl: '/flat-ui/tpls/daily-interval.html'
            };
        })
    

    现在,我正在尝试为LoadDirective编写测试用例,以测试它是否加载指令,如下所示:

    describe("loadDirective directive", function() {
        var elm, scope;
        beforeEach(module('guideApp.directives'));
        beforeEach(module('/flat-ui/tpls/daily-interval.html'));
        beforeEach(angular.mock.inject(function($rootScope, $compile) {
            scope = $rootScope;
            elm = angular.element('<load-directive type="directive" sub-type="interval" data="schedulerData"></load-directive>');
            compile = $compile;
            compile(elm)(scope);
            scope.schedulerData = {
                interval: 1,
            }
            scope.$digest();
        }));
        it("should be able to load daily directive", function() {
            scope.directive = "daily";
            var intervaldirective = elm.find('div[daily-interval-directive]');
            expect(intervaldirective.length).toEqual(1);
        });
       });
    

    这对我来说不是很好。我试着记录榆树,但它没有加载dailyInterevalDirective。

    2 回复  |  直到 9 年前
        1
  •  1
  •   Community Mohan Dere    8 年前

    这个问题有两个部分,第一个问题是 templateUrl 指令定义对象 如@r_goyal所回答 here ,无论何时通过URL加载模板,都会通过 GET 呼叫因此,您需要使用 httpBackend .

    第二部分是 $timeout .timeout异步执行,但测试同步执行。这就是你测试失败的原因。在中测试代码 $超时 我们使用 $timeout service found in angular.mock module $timeout.flush 模拟上的方法 $超时 将代码强制为原始代码的服务 $超时 同步执行。下面是一个完全正确的示例:

    describe("loadDirective directive", function() {
        var elm, scope, timeout, httpBackend;
        beforeEach(module('guideApp.directives'));
        beforeEach(module('/flat-ui/tpls/daily-interval.html'));
        beforeEach(angular.mock.inject(function($rootScope, $compile, $timeout, $httpBackend) {
            scope = $rootScope;
            timeout = $timeout;
            httpBackend = $httpBackend;
    
            elm = angular.element('<load-directive type="directive" sub-type="interval" data="schedulerData"></load-directive>');
            compile = $compile;
            compile(elm)(scope);
            scope.schedulerData = {
                interval: 1,
            }
            scope.$digest();
        }));
        it("should be able to load daily directive", function() {
            scope.directive = "daily";
            httpBackend.when('GET','/flat-ui/tpls/daily-interval.html').respond("<div> Any mock template or the original template loaded as a fixture </div>");
    
            scope.$apply();
            timeout.flush();
            httpBackend.flush();
            var intervaldirective = elm.find('div[daily-interval-directive]');
            expect(intervaldirective.length).toEqual(1);
        });
       });
    

    有几点需要注意:

    • 这就是我们所说的 scope.$apply() 作为加载指令的代码 动态地是在 .即使您将 Dtype 可变 新值的范围 手表功能 不会执行 直到 消化循环 启动。

    • 然后我们打电话 timeout.flush() 强制输入代码 $超时
      同步执行

    You can read more about testing $timeout here

    希望这有帮助

        2
  •  1
  •   r_goyal    9 年前

    看来你 dailyIntervalDirective templateUrl .

    现在,如果指令正在工作,那么在测试中,您可以预期 GET "/flat-ui/tpls/daily-interval.html" httpBackend 服务因为该模板应尽快加载 每日间隔指令 指令已编译。希望有帮助。:)


    此外,我怀疑 elm.find('div[daily-interval-directive]'); 将工作,正如在 angular docs. 那个 find() - Limited to lookups by tag name

    根据要求,请在下面找到示例代码片段:

    // -----in your spec file----  
    describe("loadDirective directive", function() {
    var elm, scope,$httpBackend;
    beforeEach(module('guideApp.directives'));
    beforeEach(angular.mock.inject(function($rootScope, $compile,$httpBackend) {
        scope = $rootScope;
        $httpBackend= $httpBackend;
        $httpBackend.whenGET('/flat-ui/tpls/daily-interval.html').respond(200, 'any response you can send here, even a blank string, as it is just to test ');
        elm = angular.element('<load-directive type="directive" sub-type="interval" data="schedulerData"></load-directive>');
        compile = $compile;
        compile(elm)(scope);
        scope.schedulerData = {
            interval: 1,
        }
        scope.$digest();
    }));
    it("should try to load daily directive's template", function() {
        scope.directive = "daily";
        $httpBackend.expectGET('/flat-ui/tpls/daily-interval.html');
        $httpBackend.flush();
    });
    });
    

    如果此测试用例通过,则表示指令已加载。