Simulate a button click in Jest

孤者浪人 提交于 2019-11-27 00:33:16

问题


Simulating a button click seems like a very easy/standard operation. Yet, I can't get it to work in Jest.js tests.

This is what I tried (and also doing it using jquery), but it didn't seem to trigger anything:

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

回答1:


#1 Using Jest

This is how I use the jest mock callback function to test the click event

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);
  });
});

I am also using a module called enzyme Enzyme is a testing utility that makes it easier to assert and select your React Components

#2 Using Sinon

Also you can use another module called sinon which is a standalone test spies, stubs and mocks for JavaScript. This is how does it look

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 Using Your own Spy

Finally you can make your own naive spy

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);
});



回答2:


Using jest you can do it like this:

test('it calls 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();
});



回答3:


Previous answers are being deprecated

Enzyme simulate is supposed to be removed in version 4. Main maintainer is suggesting directly invoking prop functions, which is what simulate does internally. One solution is to directly test that invoking those props does the right thing; or you can mock out instance methods, test that the prop functions call them, and unit test the instance methods.

You could call click for example

wrapper.find('Button').prop('onClick')() 

or

wrapper.find('Button').props().onClick() 

Information about deprecation: https://github.com/airbnb/enzyme/issues/2173




回答4:


You may use something like this to call the handler written on click:

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

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



回答5:


Additionally to the solutions that were suggested in sibling comments you may change your testing approach a little bit and test not the whole page all at once (with deep children components tree) but do an isolated component testing. This will simplify testing of onClick() and similar events (see example below).

The idea is to test only one component at a time and not all of them together. In this case all children components will be mocked using jest.mock() function.

Here is an example of how onClick() event may be tested in isolated SearchForm component using Jest and 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);
  });
});



回答6:


I needed to do a little bit of testing myself of a button component. These tests works for me ;-)

import { shallow } from "enzyme";
import * as React from "react";
import Button from "../button.component";

describe("Button Component Tests", () => {
    it("Renders correctly in DOM", () => {
        shallow(
            <Button text="Test" />
        );
    });
    it("Expects to find button HTML element in the DOM", () => {
        const wrapper = shallow(<Button text="test"/>)
        expect(wrapper.find('button')).toHaveLength(1);
    });

    it("Expects to find button HTML element with className test in the DOM", () => {
        const wrapper = shallow(<Button className="test" text="test"/>)
        expect(wrapper.find('button.test')).toHaveLength(1);
    });

    it("Expects to run onClick function when button is pressed in the DOM", () => {
        const mockCallBackClick = jest.fn();
        const wrapper = shallow(<Button onClick={mockCallBackClick} className="test" text="test"/>);
        wrapper.find('button').simulate('click');
        expect(mockCallBackClick.mock.calls.length).toEqual(1);
    });
});


来源:https://stackoverflow.com/questions/43747397/simulate-a-button-click-in-jest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!