score:172
#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 spy, stubs and mocks for JavaScript. This is how it looks:
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 (I don't recommend this approach unless you have a valid reason for that).
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);
});
score:1
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);
// The below line will execute your click function
pageMounted.instance().yourOnClickFunction();
score:1
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 a 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 the jest.mock() function.
Here is an example of how the onClick()
event may be tested in an 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);
});
});
score:1
I needed to do a little bit of testing myself of a button component. These tests work 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);
});
});
score:3
Testing-library makes this easy for you with the click function.
It's part of the user-event
library that can be used with every dom environment (react, jsdom, browser, ...)
The example from the doc:
import React from 'react'
import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
test('click', () => {
render(
<div>
<label htmlFor="checkbox">Check</label>
<input id="checkbox" type="checkbox" />
</div>,
)
userEvent.click(screen.getByText('Check'))
expect(screen.getByLabelText('Check')).toBeChecked()
})
score:13
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();
});
score:38
Solutions in accepted answer are being deprecated
#4 Calling prop directly
Enzyme simulate is supposed to be removed in version 4. The 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: Deprecation of .simulate() #2173
Source: stackoverflow.com
Related Query
- Simulate a button click in Jest
- Jest Test of Material-UI Component to Simulate Button click event to fire a Redux Action function
- Click a material-ui radio button in a jest test and see it's effect
- React Jest Enzyme - Can not get simple Button Click test to pass
- Unable to locate button to simulate click - Unit Testing React w/ Mocha, Chai, Enzyme
- How do i simulate a button click in Enzyme React?
- react testUtils simulate click on a radio button not triggering onchange
- Jest unit test - How do i simulate a click event for table row icon
- Can't seem to simulate click event with jest
- Unable to simulate click on Menu Antd with jest and enzyme
- How to do async Button click using Jest in react
- Jest - simulate is not a function on testing click on react link
- Simulate Click Test with Enzyme/ Jest Not Calling Sinon Spy
- Mock a button click in React with Jest and Enzyme
- Unable to spyon click on button using jest and react testing library for a component testcase
- React Jest Testing button click called a function
- Jest on Reactjs for simulate a click with a reference function
- How to navigate on path by button click in react router v4?
- Simulate click event on react element
- Deactivate input in react with a button click
- How to open a page in new tab on click of a button in react? I want to send some data to that page also
- Changing style of a button on click
- In reactJS, how to invoke link click via button press?
- Simulate keydown on document for JEST unit testing
- How to run an alert on button click React.js
- How to trigger onChange on <input type='file' /> by another Button click in ReactJS?
- How can I get an input's value on a button click in a Stateless React Component?
- How can I find and click a button that has no text using React Testing Library?
- React Formik bind the external button click with onSubmit function in <Formik>
- ReactJS: Download CSV File on Button Click
More Query from same tag
- Get the data from an object
- Redirect from within a React.Component
- How to add line spacing and multiple new lines in react wyswig editor
- How to prevent random numbers from generating again?
- Antd Modal, clicking on Mask to not do anything
- React JSON is undefined
- How to to access state variables or let,const,var variables of one component in other component in React.js?
- Correct way to type a 'setState' function using React hook useState()
- REGEXP help need to render 404 path
- How to properly create date object for function
- How to define a .map list in a React component that has an empty array?
- Image not showing on device for React Native movies tutorial on existing application
- How to prevent click event for one component from another?
- How to spy on function from specific button click using sinon?
- 'ItemIsLoading' on refers to a type, but is being used as a value here
- How to send multiple images form react
- Is there a way I can use js which I declared inside jsx in emotion styled components?
- Get data from Redux thunk
- handleClick selected true when I choose a MenuItem ReactJS
- Spring framework HttpMessageNotReadableException: Required request body is missing
- how to do a if in a export default
- Problem with Re-rendering when passing a React function with React Context API
- Render Props vs HOC?
- How to extract table as an indipendente component
- Problem with using Material UI <Grid> for two column layout
- Error: useRoutes() may be used only in the context of a <Router> component
- Listener not getting removed on component unmount in React
- react native and useFocusEffect duplicate data when navigating back
- Reactjs -- parent, child - state handling architecture for each
- React.js, how to send a multipart/form-data to server