简体   繁体   中英

AngularJS, Jasmine test promise does not resolve

I cannot get my promise to resolve in my tests. I have two services.

1- A ServerApiService that normally makes the call to the server:

angular.module('test').service('serverApiService', ['$http', function($http) {
    var self = this;

    self.generateRequest = function(actionName, data) {
        console.log('request generated');
        //normally returns 'return $http(config);'
    };

}]);

2- A second service uses ServerApiService, and manages the solutions, SolutionService :

angular.module('test').service('solutionService', ['$q', 'serverApiService', function($q, serverApiService) {
    var self = this;

    self.list = function(account) {
        var data = {
          id: account.id
        };

        var deferred = $q.defer();

        serverApiService.generateRequest('solutions.list', data).then(function(response) {
            var solutions = [];

            for(var i = 0; i < response.Items.length; i++) {
                var solutionJSON = response.Items[i];
                var studyJSON = solutionJSON.Study;

                var solution = {};
                solution.id = solutionJSON.Id;

                var study = {};
                study.name = studyJSON.Name;


                solution.study = study;
                solutions.push(solution);
            }

            deferred.resolve(solutions);
        });

        return deferred.promise;
    };

}]);

Testing problems

I want to test the SolutionService module so I created a mock of the ServerApiService but I can't get the spy function to return the promise and I don't know why:

describe('solution service', function () {

    var mockServerApiService, solutionSvc;

    beforeEach(function() {
        module('test');
    });

    beforeEach(function() {
        module(function($provide) {
            $provide.service('serverApiService', function($q) {
                this.generateRequest = jasmine.createSpy('generateRequest').and.callFake(function(actionName, data) {
                    var deferred = $q.defer();

                    deferred.resolve({Items: [
                      {
                        Id: '910759',
                        Study: {
                          Id: '213123',
                          Name: 'test'
                        },
                      },
                      {
                        Id: '4406510',
                        Study: {
                          Id: '063294',
                          Name: 'test2'
                        },
                      }, 
                      ]});

                    return deferred.promise;
                });
            });
        });

    });



    beforeEach(inject(function (serverApiService, solutionService) {
        mockServerApiService = serverApiService;
        solutionSvc = solutionService;
    }));


    it('should return all the solutions', function(done) {
        var account = {};
        account.id = 'test@test.com';
        solutionSvc.list(account).then(function(solutions) {
            expect(solutions.length).toBe(2);
            done();
        });

        expect(mockServerApiService.generateRequest).toHaveBeenCalled();

    })



});

Basically the then portion in SolutionService is never called:

serverApiService.generateRequest('solutions.list', data).then(function(response) {
                //Never called
});

Here's a plunker of the situation: http://plnkr.co/edit/gMyaOpfczBmt9HhwzI9m?p=preview

You need to kick off an angular digest in order for the promise to resolve. I've forked your plunk and fixed by injecting a new scope and calling apply on it inside your test. See here: http://plnkr.co/edit/Nrlg7KwfwTNJW3gpAG1m

var mockServerApiService, solutionSvc, scope;

    beforeEach(function() {
        module('test');
    });

    beforeEach(function() {
        module(function($provide) {
            $provide.service('serverApiService', function($q) {
                this.generateRequest = jasmine.createSpy('generateRequest').and.callFake(function(actionName, data) {
                    var deferred = $q.defer();

                    deferred.resolve({Items: [
                      {
                        Id: '910759',
                        Study: {
                          Id: '213123',
                          Name: 'test'
                        },
                      },
                      {
                        Id: '4406510',
                        Study: {
                          Id: '063294',
                          Name: 'test2'
                        },
                      }, 
                      ]});

                    return deferred.promise;
                });
            });
        });

    });



    beforeEach(inject(function (serverApiService, solutionService, $rootScope) {
        mockServerApiService = serverApiService;
        solutionSvc = solutionService;
        scope = $rootScope.$new();
    }));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM