Отправка тестовой формы React с помощью Jest и TestUtils

У меня возникли проблемы с тестированием события формы submit с использованием React, TestUtils и Jest.

У меня есть компонент, который отображает элемент DOM <form>; тот же компонент также имеет метод, который обрабатывает событие onSubmit и регистрирует оператор. Моя цель — издеваться над обработчиком onSubmit и утверждать, что он вызывается.

form-component.cjsx

module.exports = React.createClass

  # Handle form submissions
  handleSubmit: (e) ->
    console.log 'Make async call'

  # Render a form
  render: ->
    <form onSubmit={@handleSubmit}>
      <input type="submit" />
    </form>

__tests__/test-form-component.coffee

jest
  .dontMock '../form-component'

React = require 'react/addons'
TestUtils = React.addons.TestUtils
FormComponent = require '../form-component'

describe 'FormComponent', ->
  it 'creates a log statement upon form submission', ->
    # Render a FormComponent into the dom
    formInstance = TestUtils.renderIntoDocument(<FormComponent />)

    # Mock the `handleSubmit` method
    formInstance.handleSubmit = jest.genMockFunction()

    # Simulate a `submit` event on the form
    TestUtils.Simulate.submit(formInstance)
    # TestUtils.Simulate.submit(formInstance.getDOMNode()) ???

    # I would have expected the mocked function to have been called
    # What gives?!
    expect(formInstance.handleSubmit).toBeCalled()

Связанные вопросы:


person cooncesean    schedule 24.11.2014    source источник


Ответы (2)


В чем именно заключается ваша проблема?

React.addons.TestUtils.Simulate.submit() у меня работает.

Если это может помочь, я был в похожей ситуации и тестировал обработчик отправки таким образом (используя sinon.js, mocha и chai):

var renderDocumentJQuery = $(renderDocument.getDOMNode())
this.xhr = sinon.useFakeXMLHttpRequest();
var requests = this.requests = [];
this.xhr.onCreate = function (xhr) {
    requests.push(xhr);
};
renderDocumentJQuery.find('input#person_email').val('[email protected]');
React.addons.TestUtils.Simulate.submit(renderDocumentJQuery.find('form')[0]);
var requestFired = requests[0];
this.xhr.restore();
it('should fire an AJAX with the right params', function(){
  assert.equal(requestFired.requestBody,'campaign_id=123&owner_id=456&person%5Bemail%5D=test%40email.com')
});
it('should fire an AJAX with a POST method', function(){
  assert.equal(requestFired.method,'POST')
});
it('should fire an AJAX with the correct url', function(){
  assert.equal(requestFired.url,'url-for-testing')
});
person Hartator    schedule 06.03.2015

Существует проблема с тем, как React вызывает обработчики событий, из-за которой исходная функция обработчика продолжает быть вызвана, даже если вы сначала попытаетесь издеваться над ним.

Очевидно, этого можно избежать, переключившись на Синтаксис класса ES6 для создания классов компонентов, но другой простой обходной путь — заставить обработчик событий просто вызывать вторую функцию и имитировать ее. Например:

onSubmit: function() {
    this.handleSubmit();  // extra fn needed for Jest
},
handleSubmit: function(){
    this.setState({
        submitted: true
    });
}

Вы бы установили форму onSubmit={this.onSubmit} и издевались над handleSubmit вместо onSubmit. Поскольку это вводит, казалось бы, ненужную дополнительную функцию, если вы решите сделать это, вероятно, стоит добавить комментарий, чтобы предвидеть последующие попытки «исправить это», которые могут нарушить тест.

person Adam Stone    schedule 14.03.2015