3
我正在測試使用Google Maps Geoencoding服務的服務。認爲它會很容易,因爲它非常簡單直接的代碼。但似乎不是。
這裏的服務:
(function() {
'use strict';
var GoogleGeocodingService = function ($q, GoogleAPILoaderService, $rootScope) {
var geocoder,
mapsReadyPromise;
mapsReadyPromise = GoogleAPILoaderService.load('maps', '3', {other_params: 'sensor=false'}).then(function() {
geocoder = new google.maps.Geocoder();
});
var getLatLng = function (searchKeyword) {
var deferred = $q.defer();
mapsReadyPromise.then(function() {
geocoder.geocode({'address': searchKeyword}, function (results, status) {
$rootScope.$apply(function() {
if (status === google.maps.GeocoderStatus.OK) {
deferred.resolve(results);
} else {
deferred.reject(status);
}
});
});
});
return deferred.promise;
};
return {
getLatLng: getLatLng
};
};
app.factory('GoogleGeocodingService', ['$q', 'GoogleAPILoaderService', '$rootScope', GoogleGeocodingService]);
}());
爲了在不使用真正的google.maps
我嘲笑兩個GoogleAPILoaderService和google.maps
。
但是,當我嘗試測試它時,我進入了$digest already in progress
。我用safeApply
嘗試過,但不起作用。
it('Should call geocoder.geocode to retrieve results', function() {
GoogleGeocoding.getLatLng('Canada');
$rootScope.$apply();
expect(GeoCoderMock.prototype.geocode).toHaveBeenCalledWith({ address : 'Canada'});
});
這是全規格:
(function() {
"use strict";
var GeoCodingOK, GeoCodingError, GeoCoderMock, GoogleAPILoaderMock, $rootScope, $q, $timeout, GoogleGeocoding;
describe('Google Geocoding Service', function() {
beforeEach(angular.mock.module('app', function($provide){
GoogleAPILoaderMock = jasmine.createSpyObj('GoogleAPILoaderService',['load']);
$provide.value('GoogleAPILoaderService',GoogleAPILoaderMock);
}));
beforeEach(inject(function (_$q_,_$rootScope_) {
$q = _$q_;
$rootScope = _$rootScope_;
GoogleAPILoaderMock.load.andCallFake(function() {
var deferred = $q.defer();
deferred.resolve('Library Loaded');
return deferred.promise;
});
}));
beforeEach(inject(function (GoogleGeocodingService) {
GoogleGeocoding = GoogleGeocodingService;
window.google = jasmine.createSpy('google');
window.google.maps = jasmine.createSpy('maps');
window.google.maps.GeocoderStatus = jasmine.createSpy('GeocoderStatus');
window.google.maps.GeocoderStatus.OK = 'OK';
GeoCodingOK = function (params, callback) {
callback({data: 'Fake'}, 'OK');
};
GeoCodingError = function (params, callback) {
callback({data: 'Fake'}, 'ERROR');
};
GeoCoderMock = window.google.maps.Geocoder = jasmine.createSpy('Geocoder');
GeoCoderMock.prototype.geocode = jasmine.createSpy('geocode').andCallFake(GeoCodingOK);
}));
it('Should expose some functions', function(){
expect(typeof GoogleGeocoding.getLatLng).toBe('function');
});
describe('getLatLng function', function() {
it('Shouldn\'t call anything if the promise hasn\'t been resolved', function() {
GoogleGeocoding.getLatLng('Canada');
expect(GeoCoderMock.prototype.geocode).not.toHaveBeenCalled();
});
it('Should return a promise', function() {
var promise = GoogleGeocoding.getLatLng('Canada');
expect(typeof promise.then).toBe('function');
});
it('Should call geocoder.geocode to retrieve results', function() {
GoogleGeocoding.getLatLng('Canada');
$rootScope.$apply();
expect(GeoCoderMock.prototype.geocode).toHaveBeenCalledWith({ address : 'Canada'});
});
it('Should resolve the promise when receiving data', function() {
var okMock = jasmine.createSpy();
GoogleGeocoding.getLatLng('Canada').then(okMock);
$rootScope.$apply();
expect(okMock).toHaveBeenCalledWith({ address : 'Canada'});
});
});
});
}());
FAQ:
- 你試過
$$phase
檢查?
是的。不起作用。不知何故,該階段在那一點是空的。我擔心通過調用$apply
我正在釋放其中兩個如何,這是造成這個問題。
- 你能爲此提供一個Plunker嗎?
當然是的!鏈接到Plunker
感謝您的! –