我只使用Jasmine和Karma(测试运行器)在AngularJS中进行了一些测试
但我现在卡住了.我正在部分视图上集成谷歌地图,我渴望在相应的控制器中测试我为它写的功能(当点击发生时放置标记,改变地图上圆圈的半径,……)
所有功能都有效,但测试似乎要困难得多.这是一个简单的测试,我用它来验证服务是否已定义:
it('should contain a locationDbService',
function () {
expect(locationDbService).toBeDefined();
});
我在每次测试之前执行了以下代码:
var ctrl, scope, locationDbService;
// inject the $controller and $rootScope services
// in the beforeEach block
beforeEach(inject(function ($controller, $rootScope, _LocationDbService_) {
// Create a new scope that's a child of the $rootScope
scope = $rootScope.$new();
// Create the controller
ctrl = $controller('AddLocationCtrl', {
$scope: scope,
LocationDbService: _LocationDbService_
});
locationDbService = _LocationDbService_;
}));
控制器头如下:
.controller('AddLocationCtrl', function ($scope, LocationDbService) {
在控制器中初始化函数:
var map;
$scope.initialize = function () {
var mapOptions = {
zoom: 15,
center: new google.maps.LatLng(51.142036, 4.440966)
};
map = new google.maps.Map(document.getElementById('map-canvas-add-location'), mapOptions);
};
google.maps.event.addDomListener(window, "load", $scope.initialize());
视图:
<div class="item item-body">
<div id="map-canvas-add-location"></div>
</div>
我在开始时遇到的问题是:
我通过将google maps js文件添加到Karma conf文件数组来“修复”它,这是一个正确的解决方案吗?
当我添加js文件并再次运行测试时,我得到以下失败:
我已经在网上搜索了几个小时的解决方案,但找不到它们中的任何一个.我究竟做错了什么?
提前致谢!
最佳答案 对于您的第一个错误屏幕,您是正确的,因为茉莉花测试运行器不包含对google maps js文件的引用.
对于第二个错误,您没有带map-canvas-add-location的div元素.您的视图确实包含div元素,但它没有在您的jasmine测试套件中加载.这是正确的行为,单元测试不应该依赖于特定的dom结构,因为它使它们更脆弱.
我知道有两种方法可以处理第二个错误:
>利用服务将特定的电话打包到谷歌地图
依赖.这就是我目前的角度图项目的工作原理.
>将所有地图级别测试转换为E2E测试而不是单元测试.
我推荐数字1,因为E2E测试不是一个轻松的步骤. E2E测试通常更脆,更难维护.
以下是包装器服务的外观示例:
.factory('GoogleMap', function(){
return {
createMap: function(element, options){
return new google.maps.Map(element, options);
},
mapOptions: {
animation: google.maps.MapTypeId.DROP,
maxZoom: 15,
mapTypeControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM,
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
}
},
markerOptions:{
animation: google.maps.Animation.DROP,
clickable: true
},
position: function(location){
return new google.maps.LatLng(location.latitude, location.longitude);
},
geocode: function(search, successFun){
var geocoder = new google.maps.Geocoder();
geocoder.geocode(search, successFun);
},
bounds: function(){
return new google.maps.LatLngBounds();
}
};
});
并在代码中使用:
var mapOptions = angular.extend({
zoom: 15,
center: GoogleMap.position({latitude: 51.142036, longitude: 4.440966})
}, GoogleMap.mapOptions);
map = GoogleMap.createMap(document.getElementById('map-canvas-add-location'), mapOptions);
然后在测试中,您需要创建一个模拟的GoogleMap服务,并在该模拟上设置间谍,以断言您的地图是否正确生成.
以下是模拟GoogleMap服务示例:
.factory('mockGoogleMap', function(){
var mapResult = {
formatted_address: 'mock formatted address',
geometry: {
location: {
lat: function(){
return 1;
},
lng: function(){
return 2;
}
}
}
};
return {
createMap: function(element, options){
return {
//add functions called by your controller on the map here
};
},
mapOptions: {},
markerOptions: {},
position: function(location){
return {latitude: location.latitude, longitude: location.longitude};
},
geocode: function(params, success){
success([mapResult], null);
},
geocodeResult: mapResult,
bounds: function(){
return {
extend: function(position){},
getCenter: function(){ return {}; }
};
},
};
});