2
votes

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

2
show your controller's code, and you can mock $http service - Max Koretskyi
Edited to show function from controller being tested. - Dean Sherwin
show where this function is referenced in code - Max Koretskyi
and now show LoginService.login :) - Max Koretskyi
Done - successCallback gets called from LoginService if response code is 201. The response object is passed to the successCallback from within LoginService. So to test the successCallback it would be easier to just pass an objected loaded and parsed from a local .json file. - Dean Sherwin

2 Answers

0
votes

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);
});
1
votes

@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 }) );