gpt4 book ai didi

angularjs - 在 karma/ Jasmine 测试中模拟 angular.service/ promise

转载 作者:行者123 更新时间:2023-12-03 06:30:51 24 4
gpt4 key购买 nike

我正在尝试编写一个 karma/ Jasmine 测试,我想要一些关于模拟如何在返回 promise 的服务上工作的解释。我解释一下我的情况:

我有一个 Controller ,我在其中执行以下调用:

mapService.getMapByUuid(mapUUID, isEditor).then(function(datas){
fillMapDatas(datas);
});

function fillMapDatas(datas){
if($scope.elements === undefined){
$scope.elements = [];
}
//Here while debugging my unit test, 'datas' contain the promise javascript object instead //of my real reponse.
debugger;
var allOfThem = _.union($scope.elements, datas.elements);

...

这是我的服务:

(function () {
'use strict';

var serviceId = 'mapService';

angular.module('onmap.map-module.services').factory(serviceId, [
'$resource',
'appContext',
'restHello',
'restMap',
serviceFunc]);

function serviceFunc($resource, appContext, restHello, restMap) {

var Maps = $resource(appContext+restMap, {uuid: '@uuid', editor: '@editor'});

return{
getMapByUuid: function (uuid, modeEditor) {
var maps = Maps.get({'uuid' : uuid, 'editor': modeEditor});
return maps.$promise;
}
};
}

})();

最后,这是我的单元测试:

describe('Map controller', function() {
var $scope, $rootScope, $httpBackend, $timeout, createController, MapService, $resource;

beforeEach(module('onmapApp'));

beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
$rootScope = $injector.get('$rootScope');
$scope = $rootScope.$new();

var $controller = $injector.get('$controller');

createController = function() {
return $controller('maps.ctrl', {
'$scope': $scope
});
};
}));

afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});

var response = {"elements":[1,2,3]};

it('should allow user to get a map', function() {

var controller = createController();
$httpBackend.expect('GET', '/onmap/rest/map/MY-UUID?editor=true')
.respond({
"success": response
});


// hope to call /onmap/rest/map/MY-UUID?editor=true url and hope to have response as the fillMapDatas parameter
$scope.getMapByUUID('MY-UUID', true);

$httpBackend.flush();
});
});

我真正想做的是将我的响应对象({“elements:...})作为fillMapDatas函数的数据参数。我不明白如何模拟所有服务事物(服务, promise ,那么)

最佳答案

您想测试您的服务是否按预期响应?那么,这是您更愿意在服务上测试的内容。基于单元测试 promise 的方法可能如下所示:

var mapService, $httpBackend, $q, $rootScope;

beforeEach(inject(function (_mapService_, _$httpBackend_, _$q_, _$rootScope_) {
mapService = mapService;
$httpBackend = _$httpBackend_;
$q = _$q_;
$rootScope = _$rootScope_;

// expect the actual request
$httpBackend.expect('GET', '/onmap/rest/map/uuid?editor=true');

// react on that request
$httpBackend.whenGET('/onmap/rest/map/uuid?editor=true').respond({
success: {
elements: [1, 2, 3]
}
});
}));

如您所见,您不需要使用 $injector,因为您可以直接注入(inject)所需的服务。如果您想在整个测试中使用正确的服务名称,您可以使用前缀和后缀“_”注入(inject)它们,inject() 足够智能,可以识别您所指的服务。我们还为每个 it() 规范设置了 $httpBackend 模拟。我们设置了 $q$rootScope 供以后处理。

以下是测试您的服务方法是否返回 promise 的方法:

it('should return a promise', function () {
expect(mapService.getMapUuid('uuid', true).then).toBeDefined();
});

由于 Promise 总是有一个 .then() 方法,我们可以检查这个属性来看看它是否是一个 Promise(当然,其他对象也可以有这个方法)。

接下来,您可以测试您获得的 promise 是否具有正确的值。您可以设置一个您明确解析的延迟

it('should resolve with [something]', function () {
var data;

// set up a deferred
var deferred = $q.defer();
// get promise reference
var promise = deferred.promise;

// set up promise resolve callback
promise.then(function (response) {
data = response.success;
});

mapService.getMapUuid('uuid', true).then(function(response) {
// resolve our deferred with the response when it returns
deferred.resolve(response);
});

// force `$digest` to resolve/reject deferreds
$rootScope.$digest();

// make your actual test
expect(data).toEqual([something]);
});

希望这有帮助!

关于angularjs - 在 karma/ Jasmine 测试中模拟 angular.service/ promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23991003/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com