javascript - Simuler et knappetrykk i Jest
Å simulere et knappetrykk virker som en veldig enkel/standard operasjon. Likevel får jeg det ikke til å fungere i Jest.js-tester.
Dette er hva jeg prøvde (og gjorde også ved å bruke jQuery), men det ser ikke ut til å utløse noe:
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
Svar #1
#1 Bruke Jest
Slik bruker jeg Jest-mocktilbakekallingsfunksjonen for å teste klikkeenheten:
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);
});
});
Jeg bruker også en modul som heter enzyme. Enzyme er et testverktøy som gjør det lettere å bekrefte og velge dine React-komponenter
#2 Bruke Sinon
Du kan også bruke en annen modul kalt Sinon, som er en frittstående testspy, stubber og mocks for JavaScript. Slik ser det ut:
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 Bruke din egen spion
Endelig kan du lage din egen naive spion (jeg anbefaler ikke denne tilnærmingen med mindre du har en gyldig grunn til det).
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);
});
Svar #2
Løsninger i akseptert svar blir faset ut
#4 Kalle direkte på prop
Enzyme simulate skal fjernes i versjon 4. Den viktigste vedlikeholderen foreslår å kalle prop-funksjoner direkte, noe som er det simulate gjør internt. En løsning er å teste direkte at det å kalle disse props gjør det riktige; eller du kan mocke ut instansmetoder, teste at prop-funksjonene kaller dem, og enhetsteste instansmetodene.
Du kan for eksempel kalle click:
wrapper.find('Button').prop('onClick')()
Eller
wrapper.find('Button').props().onClick()
Informasjon om utfasing: Utfasing av .simulate() #2173
Svar #3
Testing-library gjør dette enkelt for deg med klikk-funksjonen.
Det er en del av user-event-biblioteket som kan brukes med alle DOM-miljøer (React, jsdom, nettleser, ...)
Eksemplet fra dokumentet:
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()
})
Svar #4
Med Jest kan du gjøre det slik:
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();
});
