我有一个使用服务函数的指令,如下所示:
angular.module('testModule',
['serviceBeingUsed'])
.directive('testDirective', function(serviceBeingUsed) {
return {
restrict: 'AE',
templateUrl: 'testTemplate.tpl.html',
scope: {
boundVar1: "="
},
link: function(scope) {
scope.getRequiredData = function(data){
//gether data using service
serviceBeingUsed.fetchRequiredData(data).then(
function(result){
scope.requiredData = result;
}
);
};
}
};
});
在上面的指令中,我注入(inject)了我希望使用的服务,并且该服务函数在该指令“链接”内的作用域函数“getRequiredData()”中使用。
我的测试套件是这样设置的:
describe('test suite', function () {
var scope,
$rootScope,
$compile,
$q,
element,
isoScope,
serviceBeingUsed;
beforeEach(module('testModule'));
beforeEach( inject( function(_$rootScope_,
_$q_,
_$compile_,
_serviceBeingUsed_) {
$rootScope = _$rootScope_;
$compile = _$compile_;
serviceBeingUsed = _serviceBeingUsed_;
$q = _$q_;
//This is where we create the directive and it's options.
element = angular.element('<test-directive bound-var1="blabla"></test-directive>');
//We create a new scope from the rootScope.
scope = $rootScope.$new();
//Now we compile the HTML with the rootscope
$compile(element)(scope);
//digest the changes
scope.$digest();
//We retrieve the isolated scope scope of the directive
isoScope = element.isolateScope();
}));
现在我有一个运行并通过的测试,我可以监视隔离范围函数“getRequiredData()”,这个测试看起来像这样:
it('getRequiredData runs', inject(function () {
spyOn(isoScope,"getRequiredData");
isoScope.getRequiredData();
expect(isoScope.getRequiredData).toHaveBeenCalled();
}));
这证明可以测试链接函数,但是当尝试测试服务函数是否被调用时,测试失败了,我不知道为什么,服务测试如下所示:
it('serviceFunction runs', inject(function () {
spyOn(serviceBeingUsed, "serviceFunction").and.callFake(function() {
var deferred = $q.defer();
var data = "returnedDataDummy";
deferred.resolve(data);
return deferred.promise;
});
isoScope.getRequiredData();
expect(serviceBeingUsed.serviceFunction).toHaveBeenCalled();
}));
如何成功测试这里是否调用了服务函数?
最佳答案
在编写这个示例时,我已经解决了我的问题。在我的实际代码中,在测试“serviceFunction runs”中,我还包含了一个 spyOn(isoScope,"getRequiredData)"
这具有阻止函数内部功能的效果
getRequiredData()
这意味着 getRequiredData 中的服务函数永远无法运行。
为了解决这个问题,我需要为外部函数编辑 spy
来自:
spyOn(isoScope,"getRequiredData");
到:
spyOn(isoScope,"getRequiredData").and.callThrough();
这个简单的更改意味着被监视的函数也将运行其内部代码,而不仅仅是注册它已被调用。
然而,我学到的一个重要教训是不要在每个测试中做太多事情,并尽可能将测试分开。
所以澄清一下,我的失败的原始测试看起来像这样:
it('getRequiredData runs', inject(function () {
spyOn(serviceBeingUsed, "serviceFunction").and.callFake(function() {
var deferred = $q.defer();
var data = "returnedDataDummy";
deferred.resolve(data);
return deferred.promise;
});
spyOn(isoScope,"getRequiredData");
isoScope.getRequiredData();
expect(serviceBeingUsed.fetchRequiredData).toHaveBeenCalled();
expect(isoScope.getRequiredData).toHaveBeenCalled();
}));
此测试通过的修复:
it('getRequiredData runs', inject(function () {
spyOn(serviceBeingUsed, "serviceFunction").and.callFake(function() {
var deferred = $q.defer();
var data = "returnedDataDummy";
deferred.resolve(data);
return deferred.promise;
});
spyOn(isoScope,"getRequiredData").and.callThrough();
isoScope.getRequiredData();
expect(serviceBeingUsed.fetchRequiredData).toHaveBeenCalled();
expect(isoScope.getRequiredData).toHaveBeenCalled();
}));
关于testing - 如何在指令链接中监视服务功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30707925/