我在控制器中调用了服务的功能。以下是代码
服务
(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();
现在请告诉我如何模拟服务电话(可能与提供商有关)。如何使用完整的代码覆盖率测试上述功能。
我的规范文件:
$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
此代码未涵盖错误阻止并提供错误
Cannot read property 'error' of undefined
请帮助我如何在我的spec文件中编写/模拟我的服务的getMyData函数
提前致谢。
答案 0 :(得分:2)
由于.success
和.error
已经过时且已被.then(successCallback, errorCallback)
替换,您应该考虑通过一次调用替换已绑定的.success
和.error
来电到.then
方法,有两个回调作为参数:第一个是成功回调,第二个是错误回调。
如果这是你愿意做的,这是你的工作实例:
您模块,服务和控制器
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()
。因此,如果我们尝试这样做,我们总会得到如下错误:
无法读取未定义
的属性'错误'
因此,您可以使用评论/*istanbul ignore next*/
跳过此部分,或切换为.then()
。
希望这有帮助。
答案 1 :(得分:0)
您需要使用spyon,它会为您的服务创建某种模拟。您需要在测试文件中执行此操作。请检查以下代码:
spyOn(MyService, "getMyData").and.callFake(() => {
return {
error: (callback) => {
return callback({});
}
};
});
希望我回答你的问题
答案 2 :(得分:0)
这是解决方案。我也遇到过类似的问题。看来我们必须设计自己的代码,而 Jasmine 允许我们设计,自定义回调方法。 在链接中,返回该对象是Javascript方法链接的任务。使用我的解决方案,您不要需要使用然后功能
$provide.service("MyService", function () {
this.getMyData= function () {
var result = {
success: function (callback) {
callback({ ServerFileName: "myserverfilename"});
//returning main object for error callback invoke to occur
return this;
},
error: function (callback) {
callback({ ServerFileName: "myserverfilename" });
//returning this object will initialize error callback with object since you are chaining
return this;
}
};
return result;
}