Был вызван пользовательский метод тестирования компонента React с использованием Enzyme и Sinon

#reactjs #mocha.js #enzyme #should.js

#reactjs #mocha.js #enzyme #should.js

Вопрос:

Я хочу проверить, что при нажатии кнопки на моем компоненте вызывается метод, который я создал для обработки щелчка. Вот мой компонент:

 import React, { PropTypes, Component } from 'react';

class Search extends Component {

  constructor(){
    super();
    this.state = { inputValue: '' };
  }

  handleChange = (e) => {
    this.setState({ inputValue: e.target.value });
  }

  handleSubmit = (e) => {
    e.preventDefault();
    return this.state.inputValue;
  }

  getValue = () => {
    return this.state.inputValue;
  }

  render(){
    return (
      <form>
        <label htmlFor="search">Search stuff:</label>
        <input id="search" type="text" value={this.state.inputValue} onChange={this.handleChange} placeholder="Stuff" />
        <button onClick={this.handleSubmit}>Search</button>
      </form>
    );
  }
}

export default Search;
  

и вот мой тест

   import React from 'react';
  import { mount, shallow } from 'enzyme';
  import Search from './index';
  import sinon from 'sinon';

  describe('Search button', () => {

    it('calls handleSubmit', () => {
      const shallowWrapper = shallow(<Search />);
      const stub = sinon.stub(shallowWrapper.instance(), 'handleSubmit');
      shallowWrapper.find('button').simulate('click', { preventDefault() {}     });
      stub.called.should.be.true();
    });

  });
  

Вызов свойства called возвращает false . Я перепробовал множество вариантов синтаксиса, и я думаю, что, возможно, я просто упускаю что-то фундаментальное. Любая помощь будет с благодарностью принята.

Ответ №1:

Я также относительно новичок в Sinon. Обычно я передавал spy() s в реквизит компонента и проверял их (хотя вы можете использовать stub() таким же образом):

 let methodSpy = sinon.spy(),
  wrapper = shallow(<MyComponent someMethod={methodSpy} />)

wrapper.find('button').simulate('click')

methodSpy.called.should.equal(true)  

Я указываю на это, потому что считаю, что это самый простой способ модульного тестирования компонентов (тестирование внутренних методов может быть проблематичным).

В вашем примере, где вы пытаетесь протестировать внутренние методы компонента, это не сработает. Однако я столкнулся с этой проблемой, которая должна вам помочь. Попробуйте:

 it('calls handleSubmit', () => {
  const shallowWrapper = shallow(<Search />)
  let compInstance = shallowWrapper.instance()

  let handleSubmitStub = sinon.stub(compInstance, 'handleSubmit');
  // Force the component and wrapper to update so that the stub is used
  compInstance.forceUpdate()
  shallowWrapper.update()

  shallowWrapper.find('button').simulate('click', { preventDefault() {} });

  handleSubmitStub.called.should.be.true();
});  

Комментарии:

1. Второй фрагмент кода действительно проходит мой тест. Интересная статья о тестировании внутренних методов, я этого не знал. Я довольно новичок в TDD в целом, поэтому, возможно, мое понимание того, что я должен тестировать, неверно. Большое спасибо, я буду продолжать свои исследования!

2. Существуют разные мнения о том, какой должна быть граница «единицы», я не думаю, что ваш подход обязательно неверен. Но подумал, что я должен передать это, поскольку это общепринятое мнение. Приятного вам тестирования 🙂

3. Большое спасибо, это мне очень помогло, я проверил много проблем в репозитории enzyme, но он не работает с внутренним методом компонента.

4. Почти год спустя, и этот ответ спас меня. Спасибо!