Prior to adding a promise, this code/spec was successfully passing
// Code
function getAvailability() {
$.ajax({
type:"POST",
url: "/get-availability",
dataType:"json",
contentType:"application/json",
data: params,
success: function() {
// ...
},
error: function() {
console.log(">> in error")
catalogDOM.updateAvailabilityForItem(0)
}
})
}
// Spec
describe("if ajax fails", function() {
beforeEach(function() {
ajaxSpy = spyOn($, "ajax")
ajaxSpy.and.callFake(function(e) {
e.error()
})
spyOn(catalogDOM, "updateAvailabilityForItem")
getAvailability()
})
it("should call updateAvailabilityForItem with 0", function() {
expect(catalogDOM.updateAvailabilityForItem).toHaveBeenCalledWith(0)
}
})
// Console output
>> in error
But then I made the ajax fire after another async function ran. I thought I spied on things correctly, and in fact, the console.log continues to indicate that the code is running. In fact, if I mocked a return value for like so spyOn(catalogDOM, "updateAvailabilityForItem").and.returnValue("works") and then in the code wrote: console.log(catalogDOM.updateAvailabilityForItem(0)), then the log does output "works"!
Yet the spec fails. Why?
// Code
function getAvailability() {
//////// START NEW LINE
utilityOrders.checkElement('#overlay').then((selector) => {
//////// END NEW LINE
$.ajax({
type:"POST",
url: "/get-availability",
dataType:"json",
contentType:"application/json",
data: params,
success: function() {
// ...
},
error: function() {
console.log(">> in error")
catalogDOM.updateAvailabilityForItem(0)
}
})
})
}
// Spec
describe("if ajax fails", function() {
beforeEach(function() {
//////// START NEW LINE
resolved_promise = new Promise(function(resolve, reject) { resolve() })
spyOn(utilityOrders,"checkElement").and.returnValue(resolved_promise)
//////// END NEW LINE
ajaxSpy = spyOn($, "ajax")
ajaxSpy.and.callFake(function(e) {
e.error()
})
spyOn(catalogDOM, "updateAvailabilityForItem")
getAvailability()
})
it("should call updateAvailabilityForItem with 0", function() {
expect(catalogDOM.updateAvailabilityForItem).toHaveBeenCalledWith(0)
}
})
// Console output
>> in error
Try making the following changes:
The above modifications should hopefully fix it for you. Dealing with promises and tests is difficult because sometimes in the test you have to tell Jasmine that the promises that were created in the code that is being tested, wait for them to complete before doing assertions.