Вопрос или проблема
Похоже, я смог заставить это работать раньше, но теперь не могу найти свой старый код. Я смотрел на этот вопрос в поисках помощи, но пока не могу заставить мок работать.
У меня есть этот модуль ES6:
export default "default"
export const getCatFact = () => ({fact: "кошки - четвероногие"});
Который используется этим тестовым компонентом:
import React, { useContext } from "react";
import { getCatFact } from "./CatService";
const Component = () => {
const {fact} = getCatFact();
return <div data-testid="my-div">{fact}</div>
}
export default Component;
Если я пытаюсь замокировать это… как в принятом ответе Энди:
import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import Component from "./Component";
test("замокировать es6 модуль", async () => {
const mockCatFact = jest.fn();
mockCatFact.mockImplementation(() => ({fact: "замокированный"}));
jest.mock('./CatService', () => ({
__esModule: true,
default: "замокированныйDefaultExport",
getCatFact: mockCatFact
}));
render(
<Component />
);
const myDiv = await screen.findByTestId("my-div")
expect(myDiv).toHaveTextContent("замокированный");//Не проходит! значение не замокировано
});
И я пробовал это способом, похожим на ответ фалсрэлы:
import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import Component from "./Component";
import { getCatFact } from "./CatService";
test("замокировать es6 модуль", async () => {
getCatFact.mockImplementation(() => ({fact: "замокированный"}));
// получаю "TypeError: _CatService.getCatFact.mockImplementation не является функцией"
render(
<Component />
);
const myDiv = await screen.findByTestId("my-div")
expect(myDiv).toHaveTextContent("замокированный");//Не проходит! значение не замокировано
});
Но в обоих случаях я получаю незамокированное значение. Код доступен в этой репозитории. Кто-нибудь может увидеть, что я делаю не так?
Ответ или решение
Вам нужно правильно замокировать именованный экспорт из ES6 модуля в Jest. Ошибка, которую вы получаете, связана с тем, что вы пытаетесь замокировать функцию после того, как модуль уже был импортирован, что означает, что эта попытка не имеет эффекта. Чтобы решить эту проблему, вам следует замокировать модуль перед его импортированием в вашу тестовую среду.
Вот правильный способ замокировать именованный экспорт в Jest:
-
Переместите вызов
jest.mock
до импорта компонента. Это позволит Jest правильно определить замокированные значения перед использованием модуля. -
Функция
getCatFact
должна быть объектом с методом, чтобы вы могли замокировать ее корректно.
Вот пример того, как должно выглядеть ваше тестирование:
import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom';
import Component from "./Component";
// Сначала замокируем модуль
jest.mock('./CatService', () => ({
__esModule: true,
getCatFact: jest.fn(),
}));
import { getCatFact } from './CatService'; // Теперь импортируем уже замокированный метод
test("mock an es6 module", async () => {
// Настраиваем реализацию замокированной функции
getCatFact.mockImplementation(() => ({ fact: "mocked" }));
// Теперь рендерим компонент
render(<Component />);
const myDiv = await screen.findByTestId("my-div");
expect(myDiv).toHaveTextContent("mocked"); // Теперь тест должен пройти
});
Объяснение кода:
- Замокирование модуля: Мы используем
jest.mock
для модуляCatService
до его импорта, чтобы все его части были замокированы должным образом. - Замокирование
getCatFact
: Мы используемjest.fn()
для создания замокированной функции, которую мы можем настраивать в тесте. - Тест: После рендеринга компонента, мы ожидаем, что содержимое
myDiv
будет равным"mocked"
.
Такой подход обеспечит, что ваш компонент будет использовать замокированную версию функции getCatFact
. Убедитесь, что вы запускаете тесты с самого начала, чтобы изменения вступили в силу.