web-dev-qa-db-fra.com

React Test Renderer Simulating Clicks on Elements

Je teste un composant React utilisant Jest v16.0.1, react-test-renderer v15.4.0 et react-addons-test-utils v15.4.0.

Le composant a rendu un bouton:

<button
    type="button"
    className="btn btn-lg btn-primary btn-danger"
    disabled={this.state.cancelButtonDisabled}
    onClick={() => this.handleCancel()}
    ref="cancelButton"
>Cancel</button>);

Et dans mon test, je rend le composant comme ceci:

const component = renderer.create(
    <MyComponent />
);

const instance = component.getInstance();
// This works but is ugly
component.toJSON().children[1].children[0].props.onClick();
// This doesn't work
ReactTestUtils.Simulate.click(instance.refs.cancelButton);

let tree = component.toJSON();
expect(tree).toMatchSnapshot();

Quelle est la méthode recommandée pour simuler un clic sur ce bouton? Vous pouvez parcourir la représentation JSON du composant mais il semble que leur devrait être une meilleure façon.

Avant, lorsque j'utilisais ReactTestUtils.renderIntoDocument, vous pouviez transmettre une référence au composant en utilisant des références à ReactTestUtils.Simulate.click

J'ai vu cette question - Comment interagir avec les composants rendus par ReactTestRenderer/Jest mais je suppose que l'API a changé car mon instance de composant n'a pas de méthode find ().

16
Aaron Kalair

J'ai trouvé une solution. Puisque vous utilisez react, je suppose que la fonction de gestionnaire onClick est passée au bouton en tant que partie des accessoires. Vous pouvez donc y accéder via les accessoires du bouton.

component.root.findByType('button').props.onClick();

Ou si vous avez plusieurs boutons, vous pouvez le faire:

component.root.findByProps({className="btn btn-lg btn-primary btn-danger"}).props.onClick();
10
Bohan Liu

C'est peut-être trop tard, mais find est une API d'enzyme. La réponse à la question à laquelle vous avez fait allusion est supposée utilisée comme indiqué dans le commentaire.

Quelque chose comme ça devrait fonctionner.

MyComponent.jsx

import React from 'react';

class MyComponent extends React.Component {
  constructor() {
    super();
    this.state = {
      cancelButtonDisabled: false,
    };
  }
  handleCancel() {
    this.props.cancelAction();
  }
  render() {
    return (
      <button
        type="button"
        className="btn btn-lg btn-primary btn-danger"
        disabled={this.state.cancelButtonDisabled}
        onClick={() => this.handleCancel()}
        ref="cancelButton"
      >
        Cancel
      </button>
    );
  }
}

export default MyComponent;

MyComponent.test.jsx

import React from 'react';
import {mount} from 'enzyme';
import MyComponent from './MyComponent';

describe('Test MyComponent', () => {
  it('should be able to click the button', () => {
    const mockFunction = jest.fn();
    const element = mount(<MyComponent cancelAction={mockFunction} />);
    element.find('button').simulate('click');
    expect(mockFunction).toHaveBeenCalled();
  });
});

sans enzyme, cela ressemblerait à ceci.

MyComponentWithoutEnzyme.test.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from 'react-addons-test-utils';
import MyComponent from './MyComponent';

describe('Test MyComponent', () => {
  it('should be able to click the button', () => {
    const mockFunction = jest.fn();
    const element = ReactTestUtils.renderIntoDocument(
      <MyComponent cancelAction={mockFunction} />,
    );
    const button = ReactDOM.findDOMNode(element);
    ReactTestUtils.Simulate.click(button);
    expect(mockFunction).toHaveBeenCalled();
  });
});
3
daiki