如何在angularjs中测试是不是加载指令
Posted
技术标签:
【中文标题】如何在angularjs中测试是不是加载指令【英文标题】:How to test directive loaded or not in angularjs如何在angularjs中测试是否加载指令 【发布时间】:2017-04-30 17:05:57 【问题描述】:我已经编写了指令,该指令在参数中采用指令名称并将该指令动态加载为休闲:
.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'
;
)
现在我正在尝试为 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);
);
);
这对我来说不是很好。我试图记录榆树,但它没有加载dailyInterevalDirective。
【问题讨论】:
嗨 Rhushikesh,指令“loadDirective”和“dailyIntervalDirective”是否按预期工作?? 它工作正常吗?但是当我编写测试用例时,现在可以测试它的加载与否 【参考方案1】:您的 dailyIntervalDirective
似乎有一个 templateUrl
。
现在,如果指令有效,那么在测试中,您可以期待使用 httpBackend
"/flat-ui/tpls/daily-interval.html"
/strong> 服务。因为应该在编译 dailyIntervalDirective
指令后立即加载该模板。希望能帮助到你。 :)
[编辑]
我也怀疑elm.find('div[daily-interval-directive]');
是否会起作用,正如angular docs. 中提到的那样, find() - Limited to lookups by tag name
根据要求,请在下面找到示例代码sn-p:
// -----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();
);
);
如果这个测试用例应该通过,则说明指令已加载。
【讨论】:
还有其他方法,比如不使用匿名函数创建“dailyIntervalDirective”,而是创建一个命名函数,然后在测试用例中监视该函数以检查它是否被调用。 ;) 我之前做过Each(module('/flat-ui/tpls/daily-interval.html'));获取模板 不...抱歉,这不是获取模板的方式...您也不需要获取模板..您只需检查是否有http调用来获取所需的模板,如果有模板调用,则确认指令已加载【参考方案2】:这个问题有两个部分。第一个问题是指令定义对象中的templateUrl
。正如@r_goyal here 所回答的那样,每当通过URL 加载模板时,它都会通过GET
调用加载。因此,您需要使用 httpBackend
模拟它。
第二部分是$timeout
的用法。 $timeout 异步执行,但测试同步执行。这就是你测试失败的原因。为了测试$timeout
中的代码,我们使用$timeout service found in angular.mock module 模拟它。我们需要在模拟$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);
);
);
有几点需要注意:
这里我们调用scope.$apply()
作为加载指令的代码
动态地在 watch 内。即使您将Dtype
变量设置为
范围为新值,watch 函数 将不会执行
直到一个消化循环开始。
然后我们调用timeout.flush()
强制$timeout
中的代码
同步执行
You can read more about testing $timeout
here
希望对你有帮助
【讨论】:
以上是关于如何在angularjs中测试是不是加载指令的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS – 如何在 Jasmine 中为输入事件指令编写单元测试
在AngularJS指令中为$ http.get加载模板属性