#javascript #reactjs #jestjs #react-testing-library
Вопрос:
Я пытаюсь шпионить за функцией внутри функционального компонента, используя библиотеку тестирования react. Я хотел проверить, вызывалась ли handleClick
функция при каждом нажатии кнопки.
Вот выдержка из моего кода
Компонент
const Foo = () => {
const handleClick = () => {}
return <div>
<button data-testid="button" onClick={handleClick}>Continue</button>
</div>
}
Тестовый случай
it("should handle continue button click", async () => {
const { getByTestId } = render(<Foo />);
const button = getByTestId("button");
const spy = jest.spyOn(Foo, "handleClick");
act(() => {
fireEvent.click(button);
});
expect(spy).toHaveBeenCalled();
});
Ошибка, которую я получаю, выглядит следующим образом
Cannot spy the handleClick property because it is not a function; undefined given instead
Кто-нибудь может, пожалуйста, помочь?
Комментарии:
1. Тестирование внутренних деталей реализации-это не то, для чего предназначена библиотека тестирования React. Тестируйте с использованием API компонента, то есть его реквизитов и пользовательского интерфейса. Похоже, что в вашем компоненте также отсутствует идентификатор
"button"
теста, поэтому запрос не будет нацелен на элемент кнопки. Поскольку компонент не является классом, нет экземпляра, для которого можно было бы получить ссылку на метод/свойство.2. Функция, определенная внутри функции, волшебным образом не является свойством внешней функции. Не тестируйте реализацию; проверьте поведение , которое обеспечивает handleClick.
3. Я забыл упомянуть об этом здесь. Но я добавил
data-testid
@DrewReese4. @jonrsharpe имеет смысл, поэтому мне не нужно ни за чем шпионить, если я использую библиотеку тестирования react. Мне просто нужно будет проверить, какой результат ожидается, когда пользователь выполняет действие в пользовательском интерфейсе.
5. Возможно, вам придется шпионить за вещами, но тестовые двойники предназначены для сотрудников , а не для того, что вы должны тестировать.
Ответ №1:
Вы пытаетесь шпионить за handleClick, как если бы это было свойство Foo, которое является функцией.
Я могу переместить щелчок мыши в другой файл и импортировать его как в компонент, так и в тест:
handler.js
export const handleClick = () => {}
Компонент
import { handleClick } from './handler.js'
const Foo = () => {
return <div>
<button data-testid="button" onClick={handleClick}>Continue</button>
</div>
}
Тестовый случай
import * as handlers from './handler.js';
it("should handle continue button click", async () => {
const { getByTestId } = render(<Foo />);
const button = getByTestId("button");
const spy = jest.spyOn(handlers, "handleClick");
act(() => {
fireEvent.click(button);
});
expect(spy).toHaveBeenCalled();
});
Ответ №2:
Ты не хочешь за мной шпионить handleClick
. Вместо этого вы хотите проверить, какое влияние handleClick
оказал компонент. Ваш handleClick
обратный вызов-это деталь реализации, и, как правило, вы это не проверяете.