0

I am new to mocha/chai unit testing. I have following ajax call which is making a service call. I have added .fail() and .done() as a part of ajax call.

So I am not sure what I am missing here. Sorry if I am missing basic things here. Can someone please describe what's wrong here?

function searchAPIcall(endPointurl, method, search_headers, search_identifier) {
    $.ajax({
        type: method,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        url: endPointurl,
        headers: search_headers,
        xhrFields: {
            withCredentials: true
        },
        success: function success(results, xhr, XMLHttpRequest) {
            successCallback();
        },
        error: function (xhr, textStatus, error) {
           callErrorFunc();
        }
    }).fail(function (xhr, textStatus, errorThrown) {
       callFailFunc();
    }).done(function () {
        callDoneFunction();
    });
}

I have written following unit test:

describe.only('Testing searchdoctorAPIcall function', function () {
    var testurl = 'https://abc.serve.org/getData';
    beforeEach(function() {
        sinon.stub($, 'ajax');
    });

    afterEach(function() {
        $.ajax.restore();
    });

    it('should make an ajax call', function(done) {
        searchAPIcall(testurl, "GET", {"Content-Type":"application-json;charset=utf-8",X-Id":"1da9b0c8-bb52"}, "baseSearch");
        expect($.ajax.calledOnce).to.be.true; 
        done(); 
    });
});

I am always getting the following error while executing unit test.

undefined is not an object (near '...} }).fail(function (xhr,...')

But When I change my searchAPIcall function and remove the .dail() and .done() unit test is passing.

function searchAPIcall(endPointurl, method, search_headers, search_identifier) {
    $.ajax({
        type: method,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        url: endPointurl,
        headers: search_headers,
        xhrFields: {
            withCredentials: true
        },
        success: function success(results, xhr, XMLHttpRequest) {
            successCallback();
        },
        error: function (xhr, textStatus, error) {
           callErrorFunc();
        }
    })
}

Now if I run the unit test then it is passing.

should make an ajax call (passed)
Valijon
  • 12,667
  • 4
  • 34
  • 67
Henry
  • 145
  • 4
  • 14
  • You need to call `done` from the test _after_ your API call has completed and you have tested whatever values you need to test. Right now it's getting called immediately. You need something like: `$.ajax(...).done(() => { ''; done(); }).fail((e) => done(e))` – Matthew Herbst Jan 10 '19 at 20:22
  • @MatthewHerbst : Can you please show one example? Sorry I didn't follow. – Henry Jan 10 '19 at 21:42
  • Possible duplicate of [Testing asynchronous function with mocha](https://stackoverflow.com/questions/12159846/testing-asynchronous-function-with-mocha) – Matthew Herbst Jan 10 '19 at 21:48

1 Answers1

0

You need to weave the test done call into your code so that it is run after the async call and your tests finish:

function searchAPIcall(endPointurl, method, search_headers, search_identifier) {
    return $.ajax({ // return the call so it can be chained
        ...
    });
}

it('should make an ajax call', function(done) {
    searchAPIcall(
      testurl,
      "GET",
      {"Content-Type":"application-json;charset=utf-8","X-Id":"1da9b0c8-bb52"}, // Note: you are missing a " before the 'X' in this line
      "baseSearch"
    ).done(() => {
      expect($.ajax.calledOnce).to.be.true;
      done();
    }).fail(done); // Equivalent to: .fail(error => done(error)) 
});
Matthew Herbst
  • 29,477
  • 23
  • 85
  • 128