【问题标题】:Mocha testing stubbed ajax call with a .thenMocha 使用 .then 测试存根的 ajax 调用
【发布时间】:2018-02-02 11:59:31
【问题描述】:

我有一个看起来像这样的 jquery ajax 调用:

$.ajax({
  type: "GET",
  dataType: 'json',
  data: data,
  url: url
}).then((data, successFlag, xhr) => {
  this.props.someFunc(data)
})

在我的测试文件中,我使用 sinon 将 jquery ajax 调用存根,它返回一个带有数据的已解决承诺:

sinon.stub($, 'ajax')
  .returns(Promise.resolve({ data: 'test data' }))

而且我还在监视我的 someFunc(data) 函数。在我的测试中,我正在调用一个进行 ajax 调用的函数,然后期望我的 someFunc(data) 被调用。但是,期望失败了,但是当我将控制台日志放入我的 someFunc(data) 函数时,我可以看到它显然被调用了:

component.instance().makeAjaxCall()
expect($.ajax.calledOnce).to.be.true // passes
expect(someFuncSpy.calledOnce).to.be.true // fails

现在我假设它失败了,因为它在此之前检查了期望。然后执行,我尝试查找一些处理承诺测试的解决方案,但到目前为止我没有尝试过任何工作(或者我执行错误)。在我检查期望之前如何确保 .then 完成执行?

【问题讨论】:

    标签: javascript ajax testing mocha.js sinon


    【解决方案1】:

    您应该在 ajax Promise 上“注册”,并将您的期望放在 then 块中。

    类似的,

    component.instance().makeAjaxCall().then(() => {
        expect($.ajax.calledOnce).to.be.true;
        expect(someFuncSpy.calledOnce).to.be.true;
    });
    

    它对你不起作用,因为 Promise 在微任务队列上注册了一个回调,并且它在下一个滴答时运行。

    【讨论】:

    • 对不起,我模棱两可,但问题是我的 makeAjaxCall() 没有返回承诺。进行 ajax 调用只是 makeAjaxCall() 函数的一部分,所以我不能将 then 链接到我的函数上。
    • 因此,除了通过 setTimeout 或类似的方式让您期待下一个事件的外观之外,没有“等待”承诺解决的干净方法。
    【解决方案2】:

    进入 sinon 优秀的 mocking utils sinon.createFakeServer(); (http://sinonjs.org/releases/v4.1.2/fake-xhr-and-server/)

    为测试设置模拟和假服务器,调用函数,告诉假服务器响应,然后检查预期。

    在这种情况下,类似于:

    it('should call someFunc with the expected data', function () {
        var server = sinon.createFakeServer();
        server.respondWith("GET", "*",
                [200, { "Content-Type": "application/json" },
                 '[{ "id": 12, "comment": "Hey there" }]']);
        var comp = component.instance();
        var testStub = sinon.stub(comp.props, 'someFunc');
        comp.makeAjaxCall();
        this.server.respond();
    
        expect(testStub.calledOnce).to.be.true; // You should consider the sinon-chai package for nicer assertion debugging
        testStub.restore();
        server.restore();
    }
    

    就个人而言,我喜欢能够传入模拟依赖项,因为我发现它更可测试(例如,将 $.ajax 传递给构造函数,存储为实例上的 ajaxService 参数)。

    【讨论】:

      【解决方案3】:

      调用存根方法后使用done()

      it('should make an ajax call', function(done) {
          sinon.stub($, 'ajax').returns(Promise.resolve({ data: 'test data' }))
          component.instance().makeAjaxCall()
          expect($.ajax.calledOnce).to.be.true;
          done(); // let Mocha know we're done async testing
      
          expect(someFuncSpy.calledOnce).to.be.true;
      });
      

      注意:请将 done 作为参数传递给函数 -- it('', function(done) {})

      Source

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-15
        • 2016-06-24
        • 2012-05-26
        • 2016-08-26
        • 1970-01-01
        相关资源
        最近更新 更多