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

Javascript 如何在angularjs中测试指令是否加载,javascript,angularjs,unit-testing,testing,angular-directive,Javascript,Angularjs,Unit Testing,Testing,Angular Directive,我编写了一个指令,它在参数中使用指令名,并将该指令动态加载为空闲: .directive("loadDirective", function($compile, $timeout) { return { restrict: 'E', scope: { Dtype: '=type', subType: '@', data: "=data"

我编写了一个指令,它在参数中使用指令名,并将该指令动态加载为空闲:

.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));
                    })
                })
            },
        };
    })
现在,我正在尝试为loadDiretive编写测试用例,以测试它是否加载指令,如下所示:

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);
    });
   });
description(“装入指令”,函数(){
var-elm,范围;
每个模块之前(模块(“指南应用程序指令”);
每个模块之前(模块('/flat ui/tpls/daily interval.html');
beforeach(angular.mock.inject(函数($rootScope,$compile){
scope=$rootScope;
elm=角度元素(“”);
compile=$compile;
编制(elm)(范围);
scope.schedulerData={
间隔时间:1,
}
范围。$digest();
}));
它(“应该能够加载每日指令”,函数(){
scope.directive=“每日”;
var intervaldirective=elm.find('div[每日间隔指令]);
expect(间隔指令.长度).toEqual(1);
});
});

这对我来说不太好。我试图记录elm,但它没有加载dailyInterevalDirective。

您的
dailyIntervalDirective
似乎有一个
模板URL

现在,如果指令正常工作,那么在测试中,您可以使用
httpBackend
服务调用
“/flat ui/tpls/daily interval.html”
。因为该模板应该在编译了
dailyIntervalDirective
指令后立即加载。希望有帮助。:)

[编辑]
我还怀疑
elm.find('div[每日间隔指令])
将起作用,正如
find()中所述-仅限于按标记名进行查找

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

// -----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();
});
});
/----在您的规范文件中--
描述(“加载指令”,函数(){
var elm,scope,$httpBackend;
每个模块之前(模块(“指南应用程序指令”);
beforeach(angular.mock.inject(函数($rootScope,$compile,$httpBackend){
scope=$rootScope;
$httpBackend=$httpBackend;
$httpBackend.whenGET('/flat ui/tpls/daily interval.html').respond(200,“您可以在此处发送的任何响应,即使是空白字符串,因为它只是为了测试”);
elm=角度元素(“”);
compile=$compile;
编制(elm)(范围);
scope.schedulerData={
间隔时间:1,
}
范围。$digest();
}));
它(“应该尝试加载每日指令的模板”,函数(){
scope.directive=“每日”;
$httpBackend.expectGET('/flat ui/tpls/daily interval.html');
$httpBackend.flush();
});
});

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

您的
dailyIntervalDirective
似乎有一个
模板URL

现在,如果指令正常工作,那么在测试中,您可以使用
httpBackend
服务调用
“/flat ui/tpls/daily interval.html”
。因为该模板应该在编译了
dailyIntervalDirective
指令后立即加载。希望有帮助。:)

[编辑]
我还怀疑
elm.find('div[每日间隔指令])
将起作用,正如
find()中所述-仅限于按标记名进行查找

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

// -----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();
});
});
/----在您的规范文件中--
描述(“加载指令”,函数(){
var elm,scope,$httpBackend;
每个模块之前(模块(“指南应用程序指令”);
beforeach(angular.mock.inject(函数($rootScope,$compile,$httpBackend){
scope=$rootScope;
$httpBackend=$httpBackend;
$httpBackend.whenGET('/flat ui/tpls/daily interval.html').respond(200,“您可以在此处发送的任何响应,即使是空白字符串,因为它只是为了测试”);
elm=角度元素(“”);
compile=$compile;
编制(elm)(范围);
scope.schedulerData={
间隔时间:1,
}
范围。$digest();
}));
它(“应该尝试加载每日指令的模板”,函数(){
scope.directive=“每日”;
$httpBackend.expectGET('/flat ui/tpls/daily interval.html');
$httpBackend.flush();
});
});

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

问题分为两部分。第一个问题是指令定义对象中的
templateUrl
。正如@r_goyal所回答的,每当通过URL加载模板时,它都是通过
GET
调用加载的。因此,您需要使用
httpBackend
模拟它

第二部分是
$timeout
的用法$超时异步执行,但测试同步执行。这就是你考试不及格的原因。要在
$timeout
中测试代码,我们使用。我们需要在mock
$timeout
服务上使用
$timeout.flush
方法来强制原始
$timeout
中的代码同步执行。下面是一个完全更正的示例:

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);
    });
   });
description(“装入指令”,函数(){
var-elm,作用域,超时,httpBackend;
每个模块之前(模块(“指南应用程序指令”);
每个模块之前(模块('/flat ui/tpls/daily interval.html');
beforeach(angular.mock.inject(函数($rootScope、$compile、$timeout、$httpBackend){
scope=$rootScope;
超时=$timeout;
httpBackend=$httpBackend;
elm=角度元素(“”);
compile=$compile;
编制(elm)(范围);
scope.schedulerData={
间隔时间:1,
}
范围。$digest();
}));
它(“应该能够加载每日指令”,函数(){
scope.directive=“每日”;
httpBackend.when('GET','/flat ui/tpls/daily interval.html')。respond(“任何模拟模板或原始模板”