Ben Che
Ben Che

Reputation: 79

How to test an angular service that asynchronously loads JSON from $http

Still rather new to angular unit testing. I have a service in module 'example' that loads a local JSON file through the $http service and asynchronously returns the response data.

I figured out that I need to test (using Jasmine) that

my service code

  /**
   * Service to load JSON data.
   */
  .service('jsonLoader', ['$http','$timeout', 'TABLE_DATA_LOC', function($http, $timeout, TABLE_DATA_LOC) {
    this.load = function() {
      return $timeout(function() {
        return $http.get(TABLE_DATA_LOC).then(function(response) {
          return response.data;
        });
      }, 30);
    };

what I have for the test currently:

describe('jsonLoader service', function() {

  var jsonLoader, httpBackend;

  beforeEach(module("example"));

  beforeEach(inject(function(_jsonLoader_, $httpBackend) {
    jsonLoader = _jsonLoader_;
    httpBackend = $httpBackend;
  }));

  it("should load json", function() {
    httpBackend.whenGET('./mock/sample.json').respond({
        "people": [
          {
            "person": {
              "firstName": "jim",
              "lastName": "bob"
            }
          }
        ]
      });
  });
});

is the first part right, and how would I use jasmine to test the async promise?

Upvotes: 0

Views: 287

Answers (1)

Phil
Phil

Reputation: 164912

Following on from my comment, here's how I would approach it.

describe('jsonLoader service', function() {
    var uri;

    beforeEach(module('example', function($provide) {
        $provide.constant('TABLE_DATA_LOC', uri = 'mock/sample.json');
    }));

    it('should load JSON in a $timeout and return the response data', inject(function($httpBackend, $timeout, jsonLoader) {
        var responseData = 'whatever', resolved = false;

        $httpBackend.expectGET(uri).respond(responseData);

        jsonLoader.load().then(function(data) {
            expect(data).toBe(responseData);
            resolved = true;
        });

        $timeout.flush();
        $timeout.verifyNoPendingTasks();

        expect(resolved).toBeFalsy();

        $httpBackend.flush();
        $httpBackend.verifyNoOutstandingRequest();

        expect(resolved).toBeTruthy();
    }));
});

Plunker demo ~ http://plnkr.co/edit/jmc9FWjbOkpmT6Lu8kVn?p=preview

Upvotes: 1

Related Questions