Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 在karma/jasmine测试中模拟角度服务/承诺_Angularjs_Unit Testing_Karma Runner_Karma Jasmine - Fatal编程技术网

Angularjs 在karma/jasmine测试中模拟角度服务/承诺

Angularjs 在karma/jasmine测试中模拟角度服务/承诺,angularjs,unit-testing,karma-runner,karma-jasmine,Angularjs,Unit Testing,Karma Runner,Karma Jasmine,我正在尝试写一个karma/jasmine测试,我想了解一下mocks是如何处理一个返回承诺的服务的。我解释我的情况: 我有一个控制器,我在其中执行以下调用: mapService.getMapByUuid(mapUUID, isEditor).then(function(datas){ fillMapDatas(datas); }); function fillMapDatas(datas){ if($scope.elements === undefined){

我正在尝试写一个karma/jasmine测试,我想了解一下mocks是如何处理一个返回承诺的服务的。我解释我的情况:

我有一个控制器,我在其中执行以下调用:

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函数的数据参数

那么,如果您的服务响应符合预期,那么您希望对服务进行测试。基于单元测试承诺的方法可以如下所示:

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
,因为您可以直接注入所需的服务。如果您想在整个测试过程中使用正确的服务名称,您可以使用前缀和后缀“389;”注入它们,
injector()
足够智能,可以识别您所指的服务。我们还为每个
it()
规范设置了
$httpBackend
模拟。我们还设置了
$q
$rootScope
以供以后处理

下面是如何测试您的服务方法是否返回承诺:

it('should return a promise', function () {
  expect(mapService.getMapUuid('uuid', true).then).toBeDefined();
});
因为承诺总是有一个
.then()
方法,所以我们可以检查这个属性,看看它是否是承诺(当然,其他对象也可能有这个方法)

接下来,您可以使用适当的值测试您得到的解析的承诺。您可以设置一个显式解析的
延迟

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]);
});

希望这能有所帮助!

谢谢,这看起来很好。只有一个问题(我是一个非常有棱角的人):这是一个在我的服务和使用中回报承诺的好方法吗“在我的控制器中的功能是否如我所愿?我对此不是很确定。因为这是一个异步任务,所以完全可以使用promise作为您的服务方法。这就是你实际上应该如何做异步的事情。对不起,实际上我不理解最后一个“it”函数。关于expect(数据)。toEqual([某物]);“数据”总是未定义的。若我在promise.then函数中加入一条“debugger”指令,那个么就永远不会进行单元测试。你有什么想法吗?干得好,谢谢。它需要一些修正才能完成。1.您的示例缺少
$httpBackend.flush()(在问题中);2. 
mapService.getMapUuid('uuid',true)。然后(响应){
应为
mapService.getMapUuid('uuid',true)。然后(函数(响应){