web-dev-qa-db-fra.com

Simuler un clic de bouton dans Jest

Simuler un clic de bouton semble être une opération très simple/standard. Pourtant, je ne peux pas le faire fonctionner dans les tests Jest.js. 

C’est ce que j’ai essayé (et aussi de le faire en utilisant jquery), mais cela ne semble rien déclencher:

import { mount } from 'enzyme';

page = <MyCoolPage />;
pageMounted = mount(page);

const button = pageMounted.find('#some_button');
expect(button.length).toBe(1); // it finds it alright
button.simulate('click'); // nothing happens
24
foobar

# 1 Utilisation de Jest

Voici comment j’utilise la fonction de rappel simulé pour tester l’événement click

import React from 'react';
import { shallow } from 'enzyme';
import Button from './Button';

describe('Test Button component', () => {
  it('Test click event', () => {
    const mockCallBack = jest.fn();

    const button = shallow((<Button onClick={mockCallBack}>Ok!</Button>));
    button.find('button').simulate('click');
    expect(mockCallBack.mock.calls.length).toEqual(1);
  });
});

J'utilise également un module appelé enzyme Enzyme est un utilitaire de test qui facilite l'affirmation et la sélection de vos composants React.

# 2 Utilisation de Sinon

Vous pouvez aussi utiliser un autre module appelé sinon , qui est un test autonome des espions, des stubs et des simulacres pour JavaScript. Voici à quoi ça ressemble 

import React from 'react';
import { shallow } from 'enzyme';
import sinon from 'sinon';

import Button from './Button';

describe('Test Button component', () => {
  it('simulates click events', () => {
    const mockCallBack = sinon.spy();
    const button = shallow((<Button onClick={mockCallBack}>Ok!</Button>));

    button.find('button').simulate('click');
    expect(mockCallBack).toHaveProperty('callCount', 1);
  });
});

# 3 Utiliser votre propre espion

Enfin, vous pouvez faire votre propre espion naïf

function MySpy() {
  this.calls = 0;
}
MySpy.prototype.fn = function () {
  return () => this.calls++;
}

it('Test Button component', () => {
  const mySpy = new MySpy();
  const mockCallBack = mySpy.fn();

  const button = shallow((<Button onClick={mockCallBack}>Ok!</Button>));

  button.find('button').simulate('click');
  expect(mySpy.calls).toEqual(1);
});
56
Saman Shafigh

En utilisant la plaisanterie, vous pouvez le faire comme ceci: 

test('should call start logout on button click', () => {
    const mockLogout = jest.fn();
    const wrapper = shallow(<Component startLogout={mockLogout}/>);
    wrapper.find('button').at(0).simulate('click');
    expect(mockLogout).toHaveBeenCalled();
});
4
Jackgisel

Vous pouvez utiliser quelque chose comme ceci pour appeler le gestionnaire écrit sur click:

import { shallow } from 'enzyme'; // mount is not required

page = <MyCoolPage />;
pageMounted = shallow(page);
// below line will execute your click function
pageMounted.instance().yourOnClickFunction();
0
utkarsh

En plus des solutions suggérées dans les commentaires frères et sœurs, vous pouvez modifier légèrement votre approche de test et ne pas tester la page entière en même temps (avec une arborescence de composants enfants profonds), mais effectuer un composant isolé essai. Cela simplifiera les tests de onClick() et d’événements similaires (voir exemple ci-dessous).

L'idée est de tester uniquement un composant à la fois et pas tous ensemble. Dans ce cas, tous les composants enfants seront fictifs avec jest.mock () function.

Voici un exemple de la manière dont l'événement onClick() peut être testé dans un composant SearchForm isolé à l'aide de Jest et react-test-renderer .

import React from 'react';
import renderer from 'react-test-renderer';
import { SearchForm } from '../SearchForm';

describe('SearchForm', () => {
  it('should fire onSubmit form callback', () => {
    // Mock search form parameters.
    const searchQuery = 'kittens';
    const onSubmit = jest.fn();

    // Create test component instance.
    const testComponentInstance = renderer.create((
      <SearchForm query={searchQuery} onSearchSubmit={onSubmit} />
    )).root;

    // Try to find submit button inside the form.
    const submitButtonInstance = testComponentInstance.findByProps({
      type: 'submit',
    });
    expect(submitButtonInstance).toBeDefined();

    // Since we're not going to test the button component itself
    // we may just simulate its onClick event manually.
    const eventMock = { preventDefault: jest.fn() };
    submitButtonInstance.props.onClick(eventMock);

    expect(onSubmit).toHaveBeenCalledTimes(1);
    expect(onSubmit).toHaveBeenCalledWith(searchQuery);
  });
});
0
Oleksii Trekhleb