У меня есть служба под названием myHttp
, которая возвращает обещание и контроллер, который вызывает myHttp
дважды с различными параметрами.Тестирование двух разрешенных обещаний с помощью Angular/Jasmine
Чтобы проверить контроллер, я пытаюсь издеваться myHttp
с Жасмин spyOn так:
beforeEach(inject(function($controller, _$rootScope_, _$q_, myHttp) {
$scope = _$rootScope_.$new();
$q = _$q_;
deferred = $q.defer();
deferred2 = $q.defer();
spyOn(myHttp, 'call').and.callFake(fake(1)).and.returnValue(deferred.promise);
spyOn(myHttp, 'call').and.callFake(fake(2)).and.returnValue(deferred2.promise);
где fake
это функция, которая извлекает параметры, которые будут использоваться в myHttp
вызова.
Проблема в том, что я не могу объявить дважды такую же издеваемую функцию. Я получаю следующую ошибку от Жасмина:
Error: call has already been spied upon
Как можно проверить этот тест? это PLUNK
Javascript:
angular.module("mymodule", [])
.service('myHttp', function($http,$q){
this.call = function(obj) {
var defer = $q.defer();
$http({url:obj.url, data:obj.data})
.then(function (response) {
defer.resolve(response);
});
return defer.promise;
};
})
.controller('ctl', function($scope,myHttp) {
$scope.read = function (id){
var data = {};
data.id = id;
myHttp.call({url:'/getStudent', data:data})
.then(function(response) {
$scope.id = response.id;
$scope.name = response.nm;
$scope.classId = response.clsid;
var data2 = {};
data2.id = $scope.classId;
myHttp.call({url:'/getClass', data:data2})
.then(function(response) {
$scope.className = response.nm;
});
});
};
});
describe('Testing a Controller that uses a Promise', function() {
var $scope;
var $q;
var deferred;
var $timeout;
beforeEach(module('mymodule'));
beforeEach(inject(function($controller, _$rootScope_, _$q_, myHttp) {
$scope = _$rootScope_.$new();
$q = _$q_;
deferred = $q.defer();
deferred2 = $q.defer();
spyOn(myHttp, 'call').and.callFake(fake(1)).and.returnValue(deferred.promise);
spyOn(myHttp, 'call').and.callFake(fake(2)).and.returnValue(deferred2.promise);
$controller('ctl', {
$scope: $scope,
myHttp: myHttp
});
$scope.read(1)
}));
function fake (option) {
if (option==1)
return {url:'/getStudent', data: {id: 1}};
else
return {url:'/getClass', data: {id: 10}};
}
it('should resolve two promises', function() {
var student = {
id: 1,
nm: "John",
clsid: 10
};
var clazz = {
id: 10,
nm: "Math"
};
deferred.resolve(student);
$scope.$apply();
deferred2.resolve(clazz);
$scope.$apply();
expect($scope.id).toBe(student.id);
expect($scope.name).toBe(student.nm);
expect($scope.classId).toBe(student.clsid);
expect($scope.className).toBe(clazz.nm);
});
});