Вы изо всех сил пытаетесь его протестировать, потому что вы тестируете одновременно много вещей.
Вот решение, в котором я отделил ваше состояние от вашего рендеринга.
Я преобразовал ваш компонент в компонент класса так что теперь вы можете иметь доступ к состоянию и методам, используя фермент .
Примечание: ваш пример очень прост, и эти тесты могут показаться излишними. Но это хороший пример, чтобы понять, что вы тестируете, и какой инструмент, который вы можете использовать для каждого теста.
В качестве общего совета, когда вы пытаетесь протестировать что-то, обычно потому, что вы тестируете слишком много вещей .
И если вы тестируете только одну вещь, то, возможно, у вас слишком много вещей в том же месте .
import React from "react";
export default class Search extends React.Component {
constructor(props) {
super(props);
this.handleOnChange = this.handleOnChange.bind(this);
this.state = {
term: ''
}
}
handleOnChange(value) {
if (!value) {
return false;
}
this.setState({term: value});
return true;
}
render() {
return <SearchInput handleOnChange={this.handleOnChange} />
}
}
export function SearchInput(props) {
return <input data-testid="search-input" type="text" placeholder="Search"
onChange={e => props.handleOnChange(e.target.value)} />
}
Теперь мы можем протестировать каждую функцию независимо.
import React from "react";
import { render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import {shallow} from "enzyme";
import Search, {SearchInput} from "./App";
describe('Search section', () => {
describe("Search", () => {
const searchWrapper = shallow(<Search />);
it('should update the term on change', () => {
searchWrapper.instance().handleOnChange("test-input");
expect(searchWrapper.instance().state.term).toBe("test-input");
});
it("should render the search input with handleOnChange", () => {
const searchInput = searchWrapper.find(SearchInput);
expect(searchInput.props().handleOnChange).toBe(searchWrapper.instance().handleOnChange);
});
});
describe("Search input", () => {
it("should call handleOnChange callback when typing", () => {
const onChangeMock = jest.fn();
const searchInput = render(<SearchInput handleOnChange={onChangeMock} />);
userEvent.type(searchInput.getByTestId('search-input'), 'test input');
expect(onChangeMock).toBeCalledWith('test input');
});
});
});