【问题标题】:Getting timeout error when testing ajax behavior within ember component with sinon and mocha使用 sinon 和 mocha 在 ember 组件中测试 ajax 行为时出现超时错误
【发布时间】:2014-02-23 01:35:12
【问题描述】:

我正在尝试使用 mocha 和 sinon 测试 ember 组件。我想测试使用 sinon 的“useFakeXMLHttpRequest”进行 ajax 调用的组件的操作之一。但是这个测试导致超时错误。我正在使用来自https://github.com/teddyzeenny/ember-mocha-adapter 的 ember 的 mocha 测试适配器,我在云中找不到 js 文件,所以我粘贴了整个代码 - 所以它在 jsbin 中可能看起来有点乱。

这里是问题的 jsbin 链接:http://jsbin.com/usajOhE/1/

组件的代码是:

        AS.QuestionViewComponent = Ember.Component.extend({
            templateName: "components/question-view",
            actions: {
                makeAjaxCall: function() {
                    jQuery.ajax({
                        url: "/todo/items",
                        success: function(data) {

                            //callback(null, data);
                        }
                    });
                }
            }

        });

与组件关联的把手是:

<a {{action "makeAjaxCall"}} class="test-link">Make ajax call</a>   

我的测试脚本是:

        describe("Testing", function() {


            var xhr, requests;
            before(function() {

                xhr = sinon.useFakeXMLHttpRequest();
                requests = [];
                xhr.onCreate = function(req) {
                    requests.push(req);
                };

            });

            after(function() {
                xhr.restore();
            });

            beforeEach(function() {
                AS.reset();
                visit("/");
            });

            it("shoud make ajax call", function() {
                //TIMESOUT HERE                   
                click($("a.test-link:first")).then(function() {
                    console.log(requests);
                    expect(requests.length).to.be(1);
                });
            });
        });

您的帮助将不胜感激。谢谢

【问题讨论】:

    标签: ember.js ember-data mocha.js sinon


    【解决方案1】:

    很可能是因为您没有响应虚假的 ajax 请求。 ember-testing 包计算 jQuery (see pendingAjaxRequests here) 发出的未决 ajax 请求。如果该值保持为 1,则 ember-testing wait() 助手永远不会解析。

    ember-testing 包通过ajaxStart and ajaxStop filters 递增此计数器。

    澄清这里发生了什么:当您使用click() 帮助器时,这会向元素发送点击消息,然后推迟到wait() 帮助器(承诺)。这同样适用于其他帮助程序,例如 fillIn()keyEvent() 等。您可以从 wait() 源代码中的 cmets 看到,它不会在您的其他规范中继续:

    // 1. If the router is loading
    // 2. *If there are pending Ajax requests
    // 3. If there are scheduled timers or we are inside of a run loop
    

    修复:

    不幸的是,如果您从未进入测试的then 块,则无法通过requests[0].respond(...) 伪造响应。

    相反,我通过使用 sinon 的假服务器解决了这个问题:

    var server;
    
    beforeEach(function () {
      server = sinon.fakeServer.create();
      server.autoRespond = true;
      server.autoRespondAfter = 1; // ms
      App.reset();
    });
    
    afterEach(function () {
      server.restore();
    });
    
    it("should make ajax call", function() {
      // set up the fake response
      server.responses[0].response = [200, { "Content-Type": "application/json" }, '{ "todos": [] }'];
    
      visit('/')
      .click($("a.test-link:first"))
      .then(function() {
        // should make it to here now
      });
    });
    

    当您期望单个或确定顺序的 ajax 请求进入您的假服务器时,此模式可以正常工作。如果您预计会有很多请求(使用不同的路径),您可以使用 server.respondWith([regex], ...) 将某些 url 与特定响应相匹配。

    另外需要注意的是,将 ajax 调用的成功部分放入 Ember.run 中通常是一种很好的做法:

    jQuery.ajax({
      url: "/todo/items",
      success: function(data) {
        Ember.run(function () {
          //callback(null, data);
        })
      }
    });
    

    【讨论】:

    • 感谢蒂姆的详细回复。我会尝试你的修复,让你知道它是怎么回事。再次感谢。
    • 抱歉,我花了很长时间才回复这个问题,但非常感谢。
    • 在 ie8 中,我们仍然遇到这些随机超时错误,但是在将 this.timeout(TIME IN SECONDS) 设置为更大的值后,它解决了问题。
    猜你喜欢
    • 2023-04-09
    • 2015-11-23
    • 2016-06-24
    • 2018-11-27
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多