Symulacja kliknięcia przycisku wydaje się bardzo łatwą / standardową operacją. Jednak nie mogę zmusić go do działania w testach Jest.js.
Oto, co próbowałem (i robię to również przy użyciu jQuery), ale nie wydawało się, aby cokolwiek wyzwalało:
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
console.warn
do funkcji, która działa onClick, aby sprawdzić, czy zadziała w konsoli Jest?MyCoolPage
komponentu, w przeciwnym razie trudno będzie ustalić, jaki jest rzeczywisty problem.Odpowiedzi:
# 1 Używanie Jest
Oto jak używam funkcji wywołania zwrotnego Jest mock do testowania zdarzenia kliknięcia:
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); }); });
Używam również modułu o nazwie enzym . Enzyme to narzędzie testowe, które ułatwia sprawdzanie i wybieranie komponentów React
# 2 Korzystanie z Sinon
Możesz także użyć innego modułu o nazwie Sinon, który jest samodzielnym szpiegiem testowym, kodami i próbami dla JavaScript. Tak to wygląda:
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 Używanie własnego szpiega
Wreszcie możesz stworzyć własnego naiwnego szpiega (nie polecam tego podejścia, chyba że masz ku temu ważny powód).
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); });
źródło
onChange
funkcji, któravalue
pasuje dovalue
atrybutu elementu wejściowego ? Dzięki!handleClick
metodę po kliknięciu. Jak sprawdzić, czyhandleClick
rzeczywiście został wywołany po kliknięciu przycisku?Rozwiązania w zaakceptowanej odpowiedzi są przestarzałe
# 4 Bezpośrednie wywołanie rekwizytu
Enzyme simulate ma zostać usunięty w wersji 4. Główny opiekun sugeruje bezpośrednie wywoływanie funkcji prop, co jest tym, co simulate robi wewnętrznie. Jednym z rozwiązań jest bezpośrednie sprawdzenie, czy wywołanie tych właściwości działa właściwie; lub możesz wyszydzać metody instancji, sprawdzić, czy wywołują je funkcje prop, i przetestować jednostkowe metody instancji.
Możesz nazwać kliknięcie, na przykład:
wrapper.find('Button').prop('onClick')()
Lub
wrapper.find('Button').props().onClick()
Informacje o wycofaniu: Wycofanie .simulate () # 2173
źródło
wrapper.update()
jednego z nich, ponieważ enzym może nie być w stanie zauważyć, że nastąpiła zmiana.onClick
rekwizytu? Takich jak przycisktype="submit"
wewnątrz<form />
? Tak, można przywołaćonSubmit
formularz - ale to nie jest idealne. Użytkownicy klikną przycisk i właśnie to chcesz przetestować.Używając Jest możesz to zrobić w następujący sposób:
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(); });
źródło
Możesz użyć czegoś takiego, aby wywołać program obsługi napisany po kliknięciu:
import { shallow } from 'enzyme'; // Mount is not required page = <MyCoolPage />; pageMounted = shallow(page); // The below line will execute your click function pageMounted.instance().yourOnClickFunction();
źródło
Oprócz rozwiązań, które zasugerowano w komentarzach dla rodzeństwa, możesz nieco zmienić podejście do testowania i przetestować nie całą stronę naraz (z głębokim drzewem komponentów potomnych), ale wykonać test izolowanych komponentów. Uprości to testowanie
onClick()
i podobnych zdarzeń (patrz przykład poniżej).Chodzi o to, aby testować tylko jeden komponent naraz, a nie wszystkie razem. W tym przypadku wszystkie komponenty potomne będą mockowane za pomocą funkcji jest.mock () .
Oto przykład, jak
onClick()
zdarzenie można przetestować w izolowanymSearchForm
komponencie przy użyciu Jest i mechanizmu renderującego reakcję .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); }); });
źródło
Musiałem trochę przetestować komponent przycisku. Te testy działają na mnie ;-)
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); }); });
źródło