茉莉花间谍在被承诺消耗时失败

jasmine spy failing when being consumed by a promise

// CODE

var catalogDOM = (function() {
  return {
    updateAvailabilityForItem: function(quant) {
      console.log(">>>> in updateAvailabilityForItem")
    },
    syncAvailability: function() {
      return new Promise(function(resolve, reject) {
        ...
      })
    }
  }
})();

$(document).on("click", ".item_info", function() {
  console.log(">> calling sync")
  catalogDOM.syncAvailability()
  .catch(function() {
    console.log(">>> caught")
    catalogDOM.updateAvailabilityForItem(0)
  })
})

// SPEC

describe("click on item_info", function() {
  beforeEach(function() {
    info_btn = affix(".item_info")

    spyOn(catalogDOM, "updateAvailabilityForItem")
    syncFunction = spyOn(catalogDOM, "syncAvailability")
    syncFunction.and.returnValue(new Promise(function(resolve, reject) {reject()}))
    info_btn.click()
  })
  it("should call updateAvailabiliytForItem", function() {
    expect(catalogDOM.updateAvailabilityForItem).toHaveBeenCalledWith(0)
  })
})

// CONSOLE OUTPUT

>> calling sync
>>> caught
>>>> in updateAvailabilityForItem

上面的规范失败了,此外,我可以通过控制台看到,看到上面的消息,catalogDOM.updateAvailabilityForItem 实际上是通过...调用的,是否有一些关于否定间谍的承诺设置?

问题是 promise 是异步发生的(在稍后的时间点),当你期望的时候,它还为时过早。

为了快速解锁,您可以将期望包装在 setTimeout 中,这会将 setTimeout 中发生的事情的优先级降低到 promise 之后,但我不确定这是否是好方法。

// add done to function argument
it("should call updateAvailabiliytForItem", function(done) {
    setTimeout(() => {
      expect(catalogDOM.updateAvailabilityForItem).toHaveBeenCalledWith(0);
      // call done to let Jasmine know your asynchronous work is done.
      done();
    }, 100);
  })

您可以在此处阅读有关在 Jasmine 中测试异步内容的更多信息:https://jasmine.github.io/tutorials/async

我通常使用 async/await 进行异步任务。