Получение ошибки тайм-аута при тестировании поведения ajax в компоненте ember с помощью sinon и mocha

Я пытаюсь протестировать компонент Ember с мокко и синон. Я хотел протестировать одно из действий компонента, который выполняет ajax-вызов, используя «useFakeXMLHttpRequest» синона. Но этот тест вызывает ошибку тайм-аута. Я использую тестовый адаптер mocha для ember, взятый с https://github.com/teddyzeenny/ember-mocha-adapter, я не смог найти 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);
                });
            });
        });

Ваша помощь будет высоко оценена. Спасибо


person Deewendra Shrestha    schedule 30.01.2014    source источник


Ответы (1)


Скорее всего, это потому, что вы не ответили на поддельный запрос ajax. Пакет ember-testing подсчитывает ожидающие запросы ajax, сделанные jQuery (см. ожидающие AjaxRequests здесь). Если он останется равным 1, хелпер wait() никогда не разрешится.

Пакет ember-testing увеличивает этот счетчик через фильтры ajaxStart и ajaxStop.

Чтобы пояснить, что здесь происходит: когда вы используете вспомогательную функцию click(), она отправляет сообщение о клике элементу, а затем откладывает выполнение вспомогательной функции wait() (обещание). То же самое относится и к другим помощникам, таким как fillIn(), keyEvent() и т. д. Из комментариев в исходном коде для wait() видно, что он не будет развиваться с остальными вашими спецификациями:

// 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);
    })
  }
});
person tstirrat    schedule 14.02.2014
comment
Спасибо Тим за подробный ответ. Я попробую ваше исправление и дам вам знать, как оно идет. Спасибо еще раз. - person Deewendra Shrestha; 19.02.2014
comment
Извините, мне потребовалось некоторое время, чтобы вернуться к этому, но большое спасибо. - person Deewendra Shrestha; 27.02.2014
comment
В ie8 каким-то образом мы все еще получали эти случайные ошибки тайм-аута, но после установки this.timeout(TIME IN SECONDS) на какое-то большее значение это решило проблему. - person Deewendra Shrestha; 25.03.2014