React-testing-library: изменения из-за ввода
Я пытаюсь проверить, что компонент обновляется как следует из-за изменений в элементе ввода. Я использую fireEvent.change()
-функция, и если я тогда проверю значение узла, который я нашел с помощью getByPlaceholderText
он обновился как надо. Однако я не вижу изменений в самом компоненте реакции.
Это может быть потому, что изменения не произойдут до повторного рендеринга; как бы это проверить? реагировать тестирование-библиотеки rerender
появляется для запуска компонента "с нуля" (т.е. без нового входного значения), и waitForElement
никогда не найдет то, что ждет.
Вот компонент TestForm.js:
import React from 'react';
import { withState } from 'recompose';
const initialInputValue = 'initialInputValue';
const TestForm = ({ inputValue, setInputValue }) => (
<>
{console.log('inputValue', inputValue)}
<input value={inputValue} onChange={(e) => setInputValue(e.target.value)} placeholder="placeholder" />
{inputValue !== initialInputValue && <div>Input has changed</div>}
</>
);
export default withState('inputValue', 'setInputValue', initialInputValue)(TestForm);
И вот тест, запустить с помощью npx jest test.js
:
import React from 'react';
import { cleanup, fireEvent, render, waitForElement } from 'react-testing-library';
import TestForm from './TestForm';
afterEach(cleanup);
describe('TestForm', () => {
it('Change input', async () => {
const { getByPlaceholderText, getByText } = render(<TestForm />);
const inputNode = getByPlaceholderText('placeholder');
fireEvent.change(inputNode, { target: { value: 'new value' } });
console.log('inputNode.value', inputNode.value);
await waitForElement(() => getByText('Input has changed'));
});
});
2 ответа
Этот код работает для меня:
import React from "react";
const initialInputValue = "initialInputValue";
class TestForm extends React.Component {
constructor(props) {
super(props);
this.state = { inputValue: initialInputValue };
}
render() {
const { inputValue } = this.state;
return (
<div>
{console.log("inputValue", inputValue)}
<input
value={inputValue}
onChange={e => this.setState({ inputValue: e.target.value })}
placeholder="placeholder"
/>
{inputValue !== initialInputValue && <div>Input has changed</div>}
</div>
);
}
}
import { render, cleanup, fireEvent } from "react-testing-library";
import "jest-dom/extend-expect";
afterEach(cleanup);
test("form", () => {
const { getByPlaceholderText, getByText } = render(<TestForm />);
fireEvent.change(getByPlaceholderText("placeholder"), {
target: { value: "new value" }
});
expect(getByText("Input has changed")).toBeInTheDocument();
});
Это не работает в codeandbox, хотя, я думаю, у них есть некоторые проблемы с разделением браузера и тестовой среды.
использование библиотеки пользовательских событий
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
afterEach(cleanup);
test("form", async () => {
const user = userEvent.setup();
const { getByPlaceholderText, getByText } = render(<TestForm />);
await user.type(getByPlaceholderText("placeholder"), "new value");
await waitFor(() => {
expect(getByText("Input has changed")).toBeInTheDocument();
});
});