Jasmine AJAX spy failure

125 Views Asked by At

Ok these tests were passing a few bit ago. I have made no changes to which version of jasmine I'm using but... can anyone see obvious syntax errors here?

describe("ajax return", function() {
  beforeEach(function() {
    ajaxSpy = spyOn($, "ajax")
  })
  describe("on success", function() {
    beforeEach(async function() {
      ajaxSpy.and.callFake(function(e) {
        e.success({"success":true, "remove":{1:"test"},"assign_prestock":"test2"})
      })
      await catalogDOM.syncAvailability(null)
    })
    it("should call", function() {
      ...
    })
  })
})

When running, I'm getting this error:

1_catalogDOM_spec.js:518 Uncaught (in promise) TypeError: e.success is not a function

UPDATE code for catalogDOM.syncAvailability

catalogDOM.syncAvailability: function(item_name_id) {
  return new Promise(function(resolve, reject) {
    $.ajax({
      type:"POST",
      url: "/retrieve-options-availability",
      dataType:"json",
      contentType:"application/json",
      data: JSON.stringify(params)
    })
    .done(function(response, status_string, jqxhr) {
       if (response["success"] == true) {
         resolve()
       } else {
         reject(response["message"])
       }
    })
    .fail(function(jqxhr, error_string, exception_object){
      reject("Error loading availability. Refresh & try again or contact us if this persists.")
    })
  }
1

There are 1 best solutions below

14
AliF50 On

Try doing this to debug:

ajaxSpy.and.callFake(function(e) {
        // add console.log here !!
        console.log('e: ', e);
        e.success({"success":true, "remove":{1:"test"},"assign_prestock":"test2"})
      })

Apparently, .success is not a function anymore and you can look at the value of e there. I am thinking e is the argument for what's provided in $.ajax(/* e is here */);.

Looking at the documentation here: https://api.jquery.com/jquery.ajax/, I think we need to mock a done function.

Try this:

ajaxSpy.and.callFake(function (e) {
  return {
    done: function () {
       return {
        "success":true, 
        "remove":{1:"test"},
        "assign_prestock":"test2",
        // edit - create a fail function that's empty here
        fail: function() {
          // leave empty
        }
      };
    }
  };
});

Edit Instead of doing a spy on ajaxSpy, try spying on catalogDOM directly. Something like this:

spyOn(catalogDOM, 'syncAvailability').and.resolveTo({/* Mock value here */ });

Or

spyOn(catalogDOM, 'syncAvailability').and.returnValue(Promise.resolve({ /* Mock value here */ });

And then you don't have to await it.