Promises don't resolve in Restangular service unit test

883 Views Asked by At

I have a service:

angular.module('driveby').factory('BuildingsService', function(Restangular) {
    var buildings = [];

    var fetchBuildings = function() {
        return Restangular.all('buildings').getList();
    };

    var getBuildings = function() {
        return buildings;
    };

    return {
        getBuildings: getBuildings,
        fetchBuildings: fetchBuildings
    };
});

I'm trying to unit test this using Jasmine, but the promise never resolves:

describe('BuildingsService', function () {
   var BuildingsService, httpBackend;
   var buildingsUrl = '/api/buildings';
   var mockBuildings = [
       {id: 1},
       {id: 2},
       {id: 3}
   ];

   beforeEach(module('driveby'));

   beforeEach(inject(function($httpBackend) {
       httpBackend = $httpBackend;
       httpBackend.whenGET(buildingsUrl).respond(
           JSON.stringify(mockBuildings)
       );
    }));

   beforeEach(inject(function(_BuildingsService_) {
       BuildingsService = _BuildingsService_;
   }));

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

   it('can fetch the list of buildings from the API', function() {
       expect(BuildingsService.getBuildings().length).toEqual(0);

       httpBackend.expectGET(buildingsUrl);

       BuildingsService.fetchBuildings().then(function(buildings) {
           expect(buildings.length).toEqual(3);
       });

       httpBackend.flush();

       expect(BuildingsService.getBuildings().length).toEqual(3);
   });
});

The problem is that this line never executes in the test:

expect(buildings.length).toEqual(3);

The API route is correct and there are no outstanding requests, but httpFlush is not resolving Restangular's promise. This line should pass, but it returns 0 instead of 3:

expect(BuildingsService.getBuildings().length).toEqual(3);

Anyone see what's wrong here?

1

There are 1 best solutions below

0
On

Expects inside of promise callbacks do not work. The correct way to test promises like this is to assign the returned value to a variable outside of the promise's scope.

Your second expect is returning 0 because your service's fetchBuildings() does not set the buildings array to the result of the API call; it just returns. You should add that assignment to your function, or create a variable in the test that is given the value of the API call's return, and then check that with expect();