我已經得到了具有以下方法(及其他)服務,它返回一個HTTP $承諾
function sessionService($http, serviceRoot) {
return {
getAvailableDates: function() {
return $http.get(serviceRoot + '/session/available_dates');
}
};
};
angular.module('app').service('sessionService', ['$http', 'serviceRoot', sessionService]);
然後另一家工廠將其包裝並緩存/向localStorage添加數據。這返回一個正常的承諾
angular.module('app')
.factory('AvailableDates', AvailableDates);
AvailableDates.$inject = ['sessionService', '$window', '$q'];
function AvailableDates(sessionService, $window, $q) {
var availableDates = [];
return {
getAvailableDates: getAvailableDates
};
function getAvailableDates() {
var deferred = $q.defer();
var fromStorage = JSON.parse($window.sessionStorage.getItem('validDates'));
if (availableDates.length > 0) {
deferred.resolve(availableDates);
} else if (fromStorage !== null) {
deferred.resolve(fromStorage);
} else {
sessionService.getAvailableDates()
.success(function (result) {
availableDates = result;
$window.sessionStorage.setItem('validDates', JSON.stringify(availableDates));
deferred.resolve(availableDates);
});
}
return deferred.promise;
}
}
這一切工作正常。我的問題是我無法弄清楚如何在嘲笑sessionService的時候測試這個東西。我已經閱讀了所有相關的stackoverflow問題,並嘗試了各種不同的東西,但無濟於事。
這裏是我的測試目前的樣子:
describe('testing AvailableDates factory', function() {
var mock, service, rootScope, spy, window, sessionStorageSpy, $q;
var dates = [ "2014-09-27", "2014-09-20", "2014-09-13", "2014-09-06", "2014-08-30" ];
var result;
beforeEach(module('app'));
beforeEach(function() {
return angular.mock.inject(function (_sessionService_, _AvailableDates_, _$rootScope_, _$window_, _$q_) {
mock = _sessionService_;
service = _AvailableDates_;
rootScope = _$rootScope_;
window = _$window_;
$q = _$q_;
});
});
beforeEach(inject(function() {
// my service under test calls this service method
spy = spyOn(mock, 'getAvailableDates').and.callFake(function() {
return {
success: function() {
return [ "2014-09-27", "2014-09-20", "2014-09-13", "2014-09-06", "2014-08-30" ];
},
error: function() {
return "error";
}
};
});
spyOn(window.sessionStorage, "getItem").and.callThrough();
}));
beforeEach(function() {
service.getAvailableDates().then(function(data) {
result = data;
// use done() here??
});
});
it('first call to fetch available dates hits sessionService and returns dates from the service', function() {
rootScope.$apply(); // ??
console.log(result); // this is printing undefined
expect(spy).toHaveBeenCalled(); // this passes
expect(window.sessionStorage.getItem).toHaveBeenCalled(); // this passes
});
});
我已經試過各種東西,但無法弄清楚如何測試AvailableDates.getAvailableDates的結果()調用。當我使用()完成,我得到的錯誤: 超時 - 由jasmine.DEFAULT_TIMEOUT_INTERVAL規定沒有被引用異步回調withing超時(我試過覆蓋這個值,沒有運氣)。
如果我拿出做(),並調用rootScope。$適用()的。然後被調用後,我得到一個未定義的值作爲我的結果。
我在做什麼錯?
不知道,但可能存儲在一個變量的承諾太('thePromise'),然後調用'thePromise.done()',而不是'rootScope。$適用()'在您的測試 – Rhumborl
有()(在我的測試)指的是茉莉花的()完成 http://jasmine.github.io/2.2/introduction.html#section-Asynchronous_Support 我採用了棱角分明的承諾庫$ q HTTPS://docs.angularjs。組織/ API/NG /服務/ $ q 具有那麼()調用,而不是jQuery的有()調用 – JesseDahl
爲了進一步迷惑的東西,角度的$ HTTP庫返回一個特殊的承諾(其中有.success()和。錯誤回調)。 – JesseDahl