假设你有一个Angular应用程序,它显示了一个地方列表。有一个按钮可以获取您当前的位置,点击该按钮可以根据您所在位置的距离对该列表进行排序,距离最近。
要在量角器中进行测试,您希望能够单击按钮并检查列表:
it('Should order items according to distance', function () {
locButton.click();
expect(...).toBe(...); // Check that the first item on the list
// the closest to the given lat/long
});
现在,假设按钮调用控制器中的方法,控制器调用服务中的方法,服务调用navigator.geolocation.getCurrentPosition()(并且,为了更好的衡量,该调用包含在一个promise中)。测试此方法的最佳方法是模拟对getCurrentPosition()的调用并返回特定的纬度和经度,以便具有所需的效果,一直支持链到页面输出。你如何设置那个模拟?
我尝试了this answer to a similar question about Jasmine中的方法,在navigator.geolocation上创建了一个间谍,结果如下:
ReferenceError: navigator is not defined
我还尝试使用类似于this answer的结果来模拟服务,结果为:
ReferenceError: angular is not defined
更新: 找到了解决方案所以我在下面回答了我自己的问题,但我真的,真的希望有更好的答案。
答案 0 :(得分:3)
使用browser.executeScript()
直接在浏览器中运行一些JavaScript,找到way to do it。例如:
describe('Testing geolocation', function () {
beforeEach(function () {
browser.executeScript('\
window.navigator.geolocation.getCurrentPosition = \
function(success){ \
var position = { \
"coords" : { \
"latitude": "37",
"longitude": "-115" \
} \
}; \
success(position); \
}')
});
it('Should order items according to distance', function () {
locButton.click();
expect(...).toBe(...); // Check that the first item on the list
// the closest to the given lat/long
});
});
这很有效,但很难看。我尽力使传递给browser.executeScript()
的字符串尽可能可读。
修改强>
这是一个清理版本,有两个模拟成功和错误的功能:
describe('Geolocation', function () {
function mockGeo(lat, lon) {
return 'window.navigator.geolocation.getCurrentPosition = ' +
' function (success, error) {' +
' var position = {' +
' "coords" : {' +
' "latitude": "' + lat + '",' +
' "longitude": "' + lon + '"' +
' }' +
' };' +
' success(position);' +
' }';
}
function mockGeoError(code) {
return 'window.navigator.geolocation.getCurrentPosition = ' +
' function (success, error) {' +
' var err = {' +
' code: ' + code + ',' +
' PERMISSION_DENIED: 1,' +
' POSITION_UNAVAILABLE: 2,' +
' TIMEOUT: 3' +
' };' +
' error(err);' +
' }';
}
it('should succeed', function () {
browser.executeScript(mockGeo(36.149674, -86.813347));
// rest of your test...
});
it('should fail', function () {
browser.executeScript(mockGeoError(1));
// rest of your test...
});
});
答案 1 :(得分:1)
量角器测试是e2e,因此您实际上无法访问后端代码和结果。
我有一个类似的问题,当我点击表单中的提交时,我想看到我的“帖子”输出。
创建了这个,在dom中填充测试结果,所以你可以看到这样的后端内容。
不是最好的,但是没有其他方法可以做到这一点。
/////////////////////////////////////////////////////////////////
//markup added for testing
<div ng-controller="myTestDevCtrl">
<button id="get-output" ng-click="getOutput()">get output</button>
<input ng-model="output" />
</div>
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
//test controller to show ajax data coming out
myTestModule.controller('myTestDevCtrl', function($scope,dataProxy) {
$scope.getOutput = function() {
$scope.output = dataProxy.getData();
}
})
//small service to capture ajax data
.service('dataProxy',function() {
var data;
return {
setData : function(_data) {
data = decodeURIComponent(_data);
},
getData : function() {
return data;
}
}
})
.run(function($httpBackend,dataProxy) {
//the office information post or 'save'
$httpBackend.when('POST',/\/api\/offices/)
.respond(function (requestMethod, requestUrl, data, headers) {
//capture data being sent
dataProxy.setData(data);
//just return success code
return [ 200, {}, {} ];
});
});
//make myTestModule require ngMockE2E, as well as original modules
angular.module('myTestModule').requires = [
'ngMockE2E'
];
/////////////////////////////////////////////////////////////////