在控制器 jasmine 中测试服务的 .success 和 .error [英] testing .success and .error of service in controller jasmine
问题描述
我在控制器中调用了服务的函数.下面是代码
I have a call to service's function in a controller. Below is the code
服务
(function () {
'use strict';
angular.module('MyApp')
.service('MyService', ['$http', function ($http) {
return {
getMyData: function (extension) {
return $http.get('www.something.com');
}
};
}])
})();
控制器
var getMyData = function () {
MyService.getMyData(extension).success(function (results) {
//Some functionality here
})
.error(function (err, status) {
//Some functionality here
});
}
$scope.Call=function(){
getMyData();
}
$scope.Call();
现在请告诉我如何模拟服务调用(可能与提供者有关).如何在代码覆盖率完整的情况下测试上述功能.
Now please tell me how to mock the service call (may be with providers). How to test the above functions with complete code coverage.
我的规范文件:
$provide.service("MyService", function () {
this.getMyData= function () {
var result = {
success: function (callback) {
return callback({ ServerFileName: "myserverfilename"});
},
error: function (callback) {
return callback({ ServerFileName: "myserverfilename" });
}
};
return result;
}
//......
my controller initiation and other code
这段代码没有覆盖错误块并给出错误
This code is not covering error block and giving the error
Cannot read property 'error' of undefined
请帮助我如何在我的规范文件中编写/模拟我的服务的 getMyData 函数
Please help me how to write/mock the getMyData function of my service in my spec file
提前致谢.
推荐答案
由于 .success
和 .error
是旧的并且已被替换为 .then(successCallback, errorCallback)
,您应该考虑用对 .then
的单个调用替换链接的 .success
和 .error
调用有两个回调作为参数的方法:第一个是成功回调,第二个是错误回调.
Since .success
and .error
are old and have been replaced with .then(successCallback, errorCallback)
, you should consider replacing your chained .success
and .error
calls with a single call to the .then
method with two callbacks as arguments to it: first being a success callback and second being an error callback.
如果这就是您愿意做的,这里是您的工作示例:
If that's what you're willing to do, here's your working example:
您模块、服务和控制器
angular.module('MyApp', []);
angular.module('MyApp')
.service('MyService', ['$http', function ($http) {
return {
getMyData: function (extension) {
return $http.get('www.something.com');
}
};
}]);
angular.module('MyApp')
.controller('MyAppController', ['$scope', function($scope){
var extension = { foo: 'bar' };
var getMyData = function () {
MyService.getMyData(extension).then(function (results) {
//Some functionality here
}, function (err, status) {
//Some functionality here
});
}
$scope.Call=function(){
getMyData();
}
$scope.Call();
}]);
还有你的测试
describe('Controller: MyAppController', function(){
beforeEach(module('MyApp'));
var flag, extension, $q;
extension = { foo: "bar" };
beforeEach(inject(function($controller, $rootScope, _MyService_, _$q_) {
$scope = $rootScope.$new();
MyService = _MyService_;
$q = _$q_;
spyOn(MyService, 'getMyData').and.callFake(function(){
return flag ? $q.when(): $q.reject();
});
MyAppController = $controller('MyAppController', {
$scope: $scope,
MyService: MyService
});
}));
describe('function: Call', function() {
//Text for Success Callback
it('should implicitly call MyService.getMyData with an extension object', function() {
flag = true;
$scope.Call();
expect(MyService.getMyData).toHaveBeenCalledWith(extension);
});
//Text for Error Callback
it('should implicitly call MyService.getMyData with an extension object', function() {
flag = false;
$scope.Call();
expect(MyService.getMyData).toHaveBeenCalledWith(extension);
});
});
});
更新:我试过做这样的事情,但没有运气.由于 .error()
的调用被链接到 .success()
调用,所以只有在 .success()
之后才会调用它code> 已被调用,它将永远不会到达 .error()
的调用,我们将无法模拟 .error()
.所以如果我们尝试这样做,我们总是会得到这样的错误:
UPDATE:
I've tried making something like this to work but with no luck. Since .error()
's call is chained to .success()
call, and that is something that will get called only after .success()
has been called, it will never get to .error()
's call and we'll not be able to mock .error()
. So if we try doing that, we'll always get an error like:
无法读取未定义的属性错误"
Cannot read property 'error' of undefined
因此,您可以使用注释 /*istanbul ignore next*/
跳过覆盖范围中的这一部分,或者切换到 .then()
.
So either you can use the comment /*istanbul ignore next*/
to skip this part in the coverage, or switch to .then()
.
希望这会有所帮助.
这篇关于在控制器 jasmine 中测试服务的 .success 和 .error的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!