Компонент реагирования модульного тестирования, который выполняет вызовы ajax с использованием JEST

У меня есть компонент реакции, который вызывает вызов AJAX в методе componentDidMount. Пока я пытаюсь отобразить его с помощью React.addons.TestUtils, компонент отображается без вызова AJAX. Как мне протестировать компонент реакции с помощью шутки, чтобы он вызывал AJAX? Должен ли я также использовать phantomJS (или браузер, такой как env), чтобы предоставить возможности DOM реагировать на компонент?

Компонент React:

return React.createClass({

  componentDidMount : function() {
    $.ajax({
    ... makes http request
    })
  }

  render : function() {
    <div>
      //view logic based on ajax response...
    </div>
  }
});

Тестовый пример:

jest.dontMock(../MyComponent);

var React = require('react/addons');

var TestUtils = React.addons.TestUtils;

var MyComponent = require(../MyComponent);

describe('Sample Test', function(){     

    it('To Render the component', function() {

       var component = <MyComponent />;

       var DOM = TestUtils.renderIntoDocument(component);

       .... // Some other code... 
       });
})

person alok mittal    schedule 24.06.2015    source источник


Ответы (4)


Мне очень нравится Sinon.js и его способность создавать поддельный сервер, который может отвечать на запросы ajax в целях тестирования. Вы можете использовать его вместе с Jest. Вот пример того, что он может сделать для вас:

describe('MyComponent', function() {     

    it('successfully makes ajax call and renders correctly', function() {
        //create fake server
        var server = sinon.fakeServer.create();
        //make sure that server accepts POST requests to /testurl
        server.respondWith('POST', '/testurl', 'foo'); //we are supplying 'foo' for the fake response
        //render component into DOM
        var component = <MyComponent />;
        var DOM = TestUtils.renderIntoDocument(component);
        //allow the server to respond to queued ajax requests
        server.respond();
        //expectations go here
        //restore native XHR constructor
        server.restore();
    });

});

Я не уверен, насколько вы готовы включить другую структуру в свой набор тестов, поэтому не стесняйтесь игнорировать этот ответ, если он не соответствует вашим целям.

person Michael Parker    schedule 24.06.2015

Два ответа связаны с фиктивными серверами, что в некоторых случаях может быть излишним. Я дам краткое объяснение более простого способа сделать это.

Jest будет имитировать вызов $.ajax, что означает, что $.ajax.calls[0][0] будет содержать перехваченный вызов $.ajax. Затем вы можете получить доступ к обратным вызовам успешного или ошибочного вызова и вызвать их напрямую, например, $.ajax.calls[0][0].success(/* Returned data here. */).

Настройка по умолчанию для Jest автоматически издевается над всем, кроме того, что вы специально не хотите имитировать. Допустим, вы вызываете $.ajax с обратными вызовами success и error. $.ajax.calls — это массив вызовов функции $.ajax. Мы получаем первый вызов, индексируя [0], а затем первый аргумент с другим [0] ($.ajax обычно имеет только один аргумент, словарь/объект JavaScript). Это дает нам доступ к обратным вызовам успеха и ошибки, позволяя нам передавать любые произвольные входные данные, которые мы ожидаем от этих функций, и тестировать их.

Затем вы можете нормально продолжить тестирование результатов вашего ajax-вызова.

person Slithy Toves    schedule 31.10.2016

Если вам нужно только имитировать HTTP-запросы, вы также можете использовать nock. Sinon великолепен, но имеет множество дополнительных функций, которые вам могут не понадобиться.

describe('MyComponent', function() {     
  it('successfully makes ajax call and renders correctly', function() {
    // mocks a single post request to example.com/testurl
    var server = nock('http://example.com')
      .post('/testurl')
      .reply(200, 'foo');

    var component = <MyComponent />;
    var DOM = TestUtils.renderIntoDocument(component);
  });
});

Обратите внимание, что вам, вероятно, следует вызывать nock.cleanAll() после каждого теста, чтобы любые сбои или затянувшиеся насмешки не испортили следующий тест.

person Luke    schedule 20.10.2016

Поскольку ваш $.ajax высмеивается шуткой, вы не получаете ожидаемого поведения, потому что вы не получаете реальную функцию $.ajax во время выполнения.

Вам нужно смоделировать вашу функцию $.ajax, чтобы она изменила состояние реагирующего компонента. Подробности можно найти в этой шутке. Использовать

$.ajax.mock.calls

person Bharanidharan K    schedule 27.06.2015