问题描述
我在控制器中调用了服务的功能.下面是代码
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)
替换,因此您应该考虑替换链接的.success
和.error
调用只需调用.then
方法,并使用两个回调作为参数:第一个是成功回调,第二个是错误回调.
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()
被呼叫后才会被调用,因此它将永远不会到达.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:
因此,您可以使用注释/*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()
.
希望这会有所帮助.
这篇关于在控制器茉莉花中测试.success和.error服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!