Guidance on unit testing REST call in controller returning a promise

耗尽温柔 提交于 2019-12-14 02:39:00

问题


I'm able test - $scope.dvModel = DienstverlenerDetailService.query(); - accordingly. I cant figure out how to test the commented-out lines. Sure could you use some guidance on that.

angular.module('dvb.controllers').controller('ServiceFacilitatorEditController', ['$scope', 'DienstverlenerDetailService', function(

    $scope, 
    DienstverlenerDetailService) {
    'use strict';

    $scope.dvModel = DienstverlenerDetailService.query();

    /*DienstverlenerDetailService.query().$promise.then(
        function(response) {
            $scope.dvModel = response.data;
        },
        function(error) {   

        }
    );*/
}]);



describe('serviceFacilitatorEditController', function() {
    'use strict';

    beforeEach(module('dvb.ui'));

    var scope, ctrl, fact, json, $rootScope, $compile, $controller, $injector;

    beforeEach(function() {
        inject(function(_$rootScope_, _$compile_, _$controller_, _$injector_) {
            $rootScope = _$rootScope_;
            $compile = _$compile_;
            $controller = _$controller_;
            $injector = _$injector_;
        });

        jasmine.getFixtures().fixturesPath = 'base/src/main/webapp/stubs/';
        var f = readFixtures('servicefacilitator_0');
        json = JSON.parse(f);

        scope = $rootScope.$new();

        var DienstverlenerDetailService = { query: function() {} };
        spyOn(DienstverlenerDetailService, 'query').and.returnValue(json);
        ctrl = $controller('ServiceFacilitatorEditController', {
            $scope: scope,
            DienstverlenerDetailService: DienstverlenerDetailService
        });
    });

    it('it should....', function() {
        expect(scope.dvModel.data).toBe(json.data);
    });
});

Looked at a couple of other posts where $q was used, $rootscope.apply() and/or other things to resolve the promise, however I cant seem to glue it together. I grasp the concept but still feel strange that that 1 single line is able to test perfectly but the other notation isnt.

The main reason for me asking this is: 1 - I want to understand 2 - I cant just put the promise on $scope.vdModel, i need whats inside the data property wrapper.


回答1:


When you spy on DienstverlenerDetailService's query method. Return an object with the property $promise with value as a promise, you can use $q.when. Inject $q service as well.

     spyOn(DienstverlenerDetailService, 'query').
                       and.returnValue({$promise:$q.when(json)});

And in your expectation do:-

it('it should....', function() {
    scope.$digest(); //<-- Apply digest for the promise to be resolved.
    expect(scope.dvModel.data).toBe(json.data); //<-- Now set the expectation
});

Just to add on, when you create a mock service you can probably do it in a different was as well (I generally prefer), instead of creating an anonymous function to be spied upon, you could create mock object using jasmine.createSpyObj and add any number of methods on the mock that you may want to test.

  DienstverlenerDetailService = jasmine.createSpyObj('DienstverlenerDetailService', ['query']);

  DienstverlenerDetailService.query.and.returnValue({$promise:$q.when(json)});

Similarly if you have to mock other methods as well you could do:-

 DienstverlenerDetailService = jasmine.createSpyObj('DienstverlenerDetailService', ['query', 'save', 'delete', ...etc]);

 //And set return value for specific methods...


来源:https://stackoverflow.com/questions/26142558/guidance-on-unit-testing-rest-call-in-controller-returning-a-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!