Dean Sherwin
Dean Sherwin

Reputation: 498

Load local JSON into Jasmine/Karma Unit Test in AngularJS

I'm testing a callback function which accepts a response object as it's only parameter. This object is the response of a HTTP request made elsewhere so I don't want to user $httpBackend in this test as the request has nothing to do with this function.

It's in home.js which is a controller for the homepage of my app.

Here is the function being tested:

 function submitLogin() {
      LoginService.login(loginPost, ctrl.username, ctrl.password, successCallback, errorCallback);
  }

// gets called in LoginService if login reponse is 201, otherwise errorCallback called
function successCallback(response) {
    // get details needed to determine correct forms for user
    var sessionData = {
      token: response.data.token,
      user_id: response.data.user_id,
      institution_name: response.data.institution_name,
      status: response.data.status,
      form_uri: getFormURI(response.data.forms) //extracts form URI for list of available forms for particular app
    };

    ctrl.formCheckInProgress = true;

    // update users forms from backend and cache them
    FormFetcherService.updateCachedForms(sessionData.user_id, sessionData.form_uri).then(function (response) {
      if (response == 'updated') {
        toastr.success('Your forms have been updated to the newest version', 'Forms Updated');
      }
      else {
        toastr.success('Your forms are already up-to-date', 'No Update     Required');
      }
    });

}

Login Service:

    angular.module('appName').service('LoginService', ['$http', function     ($http) {
    this.login = function (url, username, password, successCallback, errorCallback) {
        var data = {
            username: username,
            password: password
        };

        $http.post(url, $.param(data), {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                },
                timeout: 10000
            }
        ).then(successCallback, errorCallback);
    }
}]);

I want to load an object which will take the place of the 'response' object being passed into the function.

Is there any way I could put a .json file in my /tests directory, load the JSON and parse it into a Javascript object and then use said object in my unit test?

I've searched around and most solutions assume a request is being made in the function being tested - which isn't the case here.

Cheers,

Dean

Upvotes: 2

Views: 2850

Answers (2)

Winter Soldier
Winter Soldier

Reputation: 2685

@dean-sherwin Though this might not actually answer the question, I'd like to share the piece of code that I've been using to load the json from a file for jasmine testing because:

  • not always do you want to keep the huge json data in one test spec
  • helps in sharing that json data across multiple specs if need be

spyOn(SomeClass, 'someMethod').and.returnValue( $.ajax({ url: "somefolder/anotherfolder/theJSONFile.json", async: false, dataType: "json" }).then(function(data) { return data }) );

Upvotes: 1

Max Koretskyi
Max Koretskyi

Reputation: 105439

You can do it like this:

var LoginService, $controller;

var formFetcherService = {
    updateCachedForms: jasmine.createSpy('sessionData');
}

var response = {
    data: {
        user_id: 4,
        forms: 'some'
    }
}

beforeEach(module(function($provide) {
    $provide.value('LoginService', {
        login: function(url, username, password, successCallback, errorCallback) {
            successCallback(response);
        }
    });

    $provide.value('FormFetcherService', formFetcherService);
}))

beforeEach(inject(function(_$controller_) {
    $controller = _$controller_;
});

it('should create sessionData', function() {
    var controller = $controller('HomeController');
    controller.submitLogin();
    expect(formFetcherService.updateCachedForms).toHaveBeenCalledWith(response.user_id, response.form_uri);
});

Upvotes: 0

Related Questions