0

Here is my code:

function sendRequestData(url, urlParameters) {
$.ajax({
    url : url,
    method : 'POST',
    headers : {
        'Accept' : 'application/json'
    },
    contentType : 'application/json',
    data : JSON.stringify(urlParameters),
    dataType : "json",
    success : function(data) {
        successCallBack(data)
    },
    error : function(data, status, errorThrown) {
        failCallBack(data, status, errorThrown)
    }
});

I want to mock and test this ajax call. Is there anyway I can do that?

Jasmine
  • 135
  • 3
  • 16
  • 1
    Possible duplicate of [Jasmine 2.0 how to handle ajax requests](http://stackoverflow.com/questions/22245991/jasmine-2-0-how-to-handle-ajax-requests) – isherwood Apr 11 '16 at 16:04
  • The jasmine.Ajax.install() is not showing up. I have added the dependency too. Also, do I call this method before or after I load the fixture? – Jasmine Apr 11 '16 at 16:06
  • @Jasmine it is a separate plugin. You need to [install it here](https://github.com/jasmine/jasmine-ajax). – Uzbekjon Apr 11 '16 at 16:14

2 Answers2

0

If your test are hard to test, this means you are doing something wrong.

In your specific case, you need follow Dependency Inversion principle (think Dependency Injection) and inject your requirements into your function. Basically, you need to pass in all the dependencies including $, successCallback and failCallback. This would let you mock your ajax calls with Jasmine's spyOn() method and then check for correct function calls.

function sendRequestData(url, urlParameters, $, successCallBack, failCallBack) {
  $.ajax({
    url : url,
    method : 'POST',
    headers : {
        'Accept' : 'application/json'
    },
    contentType : 'application/json',
    data : JSON.stringify(urlParameters),
    dataType : "json",
    success : function(data) {
        successCallBack(data)
    },
    error : function(data, status, errorThrown) {
        failCallBack(data, status, errorThrown)
    }
  });
}

Your tests might look like this. I have not checked it, but you get an idea of what I mean.

describe("sendRequestData() does correct ajax calls", function() {
  var $ok, $error, successCallback, failCallback = null;

  beforeEach(function() {
    // You can create a spy object using this syntax
    $ok = jasmine.createSpyObj('$', ['ajax']);

    // Or define it yourself like so
    $ok = {
      ajax: function(value) {
        successCallback();
      }
    };

    $error = {
      ajax: function(value) {
        failCallback();
      }
    };

    spyOn($, 'ajax');
    spyOn(successCallback);
    spyOn(failCallback);
  });

  it("calls successCallback on success", function() {
    sendRequestData('url', {}, $ok, successCallback, failCallback);
    expect($.ajax).toHaveBeenCalled();
    expect(successCallback).toHaveBeenCalled();
    expect(failCallbackCallback).not.toHaveBeenCalled();
  });

  it("calls failCallback on failure", function() {
    sendRequestData('url', {}, $error, successCallback, failCallback);
    expect($.ajax).toHaveBeenCalled();
    expect(successCallback).not.toHaveBeenCalled();
    expect(failCallbackCallback).toHaveBeenCalled();
  });
});

Or simply use jasmine-ajax plugin to mock your ajax calls.

Uzbekjon
  • 11,655
  • 3
  • 37
  • 54
  • Is there any method I can use when using jasmine-ajax. I am new to this. Thank you very much – Jasmine Apr 12 '16 at 18:03
  • Sure, the official docs have great examples [here](http://jasmine.github.io/2.0/ajax.html#section-Basic_Usage_Across_An_Entire_Suite). – Uzbekjon Apr 12 '16 at 18:10
  • How can I mock my ajaxcall using the Jasmine-ajax plugin? – Jasmine Apr 12 '16 at 18:34
  • Click here: http://jasmine.github.io/2.0/ajax.html#section-Basic_Usage_Across_An_Entire_Suite – Uzbekjon Apr 13 '16 at 01:27
  • Can I call the function that uses ajax using this? Will this cover my function? – Jasmine Apr 13 '16 at 04:25
  • Hmm... I think if you want to write tests using Jasmine, then you should learn how to use it first. Youtube has many videos. I think you should learn it first and if you have any question then ask them here. – Uzbekjon Apr 13 '16 at 06:39
0

If you are doing this on legacy code and cannot change the JS code maybe you can try as below

JS file

$.ajax({
  async      : true,
  type       : "POST",
  data       : requestPayload,
  url        : APIURL,
  contentType: "application/json",
  success    : function (response) {
    /* -- some code here --*/
  },
  error      : function (errorResponse) {
    /* -- some code here --*/
  }
});

SPEC file

it("check api call", function () { 
 var testResponse = {
    'status'    : 'ok',
    'errorCode' : '',
    'message'   : 'this is a mock response'
  };
/*...*/
  spyOn($, 'ajax').and.callFake(function(e) {
  return e.success(testResponse);
    // for failure case 
    //return e.error({
    //  'status'    : 'not_ok',
    //  'errorCode' : 'Unauthorized'
    //});
  });
  form.submit();  
  });

You can also call the e.success and return $.Deferred().resolve(testData).promise(); from what I have understood in other examples. Mocking jQuery ajax calls with Jasmine

spyOn($, 'ajax').and.callFake(function (e) {
  e.success(testData)
  return $.Deferred().resolve(testData).promise();
});