#javascript #reactjs #jestjs #react-testing-library
Вопрос:
У меня есть собственный крючок, как показано ниже
export const useUserSearch = () => {
const [options, setOptions] = useState([]);
const [searchString, setSearchString] = useState("");
const [userSearch] = useUserSearchMutation();
useEffect(() => {
if (searchString.trim().length > 3) {
const searchParams = {
orgId: "1",
userId: "1",
searchQuery: searchString.trim(),
};
userSearch(searchParams)
.then((data) => {
setOptions(data);
})
.catch((err) => {
setOptions([]);
console.log("error", err);
});
}
}, [searchString, userSearch]);
return {
options,
setSearchString,
};
};
и я хочу проверить этот крючок, но не могу имитировать userSearch
функцию, которая вызывается внутри useEffect.
кто-нибудь может помочь?
это мой тест
it('should set state and test function', async () => {
const wrapper = ({ children }) => (
<Provider store={store}>{children}</Provider>
)
const { result } = renderHook(
() => useUserSearch(),
{ wrapper }
)
await act(async () => {
result.current.setSearchString('abc5')
})
expect(result.current.options).toEqual(expected)
})
Изменение поиска пользователей
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react';
export const userSearchAPI = createApi({
reducerPath: 'userSearchResult',
baseQuery: fetchBaseQuery({baseUrl: process.env.REACT_APP_BASE_URL}),
tagTypes: ['Users'],
endpoints: build => ({
userSearch: build.mutation({
query: body => ({url: '/org/patient/search', method: 'POST', body}),
invalidatesTags: ['Users'],
}),
}),
});
export const {useUserSearchMutation} = userSearchAPI;
Комментарии:
1. Согласно вашему коду
useUserSearch
, это первый элемент в массиве, возвращенный изuseUserSearchMutation
. Итак, вы пробовали издеватьсяuseUserSearchMutation
следующим образом:jest.mock('./useUserSearchMutation'., () => [jest.fn(() => ['mock-data']])
2. я пробовал это, но это не работает. userSearch.js содержит
export const { useUserSearchMutation } = userSearchAPI
@Marcus3. Покажите код о
useUserSearchMutation
крюке4. @slideshowp2
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' export const userSearchAPI = createApi({ reducerPath: 'userSearchResult', baseQuery: fetchBaseQuery({ baseUrl: process.env.REACT_APP_BASE_URL }), tagTypes: ['Users'], endpoints: (build) => ({ userSearch: build.mutation({ query: (body) => ({ url:
/организация/пациент/поиск, method: 'POST', body, }), invalidatesTags: ['Users'], }), }), }) export const { useUserSearchMutation } = userSearchAPI
5. @NIshamMahsin Пожалуйста, добавьте код к вашему исходному вопросу.
Ответ №1:
Поскольку это именованный экспорт, вы должны вернуть объект в макет
it("should set state and test function", async () => {
jest.mock("./useUserSearchMutation", () => ({
useUserSearchMutation: () => [jest.fn().mockResolvedValue(expected)],
}));
const wrapper = ({ children }) => (
...
});
Ответ №2:
Я создал небольшой пример, основанный на вашем коде, где я издеваюсь над крючком внутри другого крючка.
hooks/useUserSearch.js
import { useEffect, useState } from "react";
import useUserSearchMutation from "./useUserSearchMutation.js";
const useUserSearch = () => {
const [text, setText] = useState();
const userSearch = useUserSearchMutation();
useEffect(() => {
const newText = userSearch();
setText(newText);
}, [userSearch]);
return text;
};
export default useUserSearch;
hooks/useUSerSearchMutation.js
Мне пришлось переместить это в его собственный файл, чтобы иметь возможность издеваться над ним, когда он вызывался внутри другого крючка.
const useUserSearchMutation = () => {
return () => "Im not mocked";
};
export default useUserSearchMutation;
App.test.js
import { render } from "react-dom";
import useUserSearch from "./hooks/useUserSearch";
import * as useUserSearchMutation from "./hooks/useUserSearchMutation";
import { act } from "react-dom/test-utils";
let container;
beforeEach(() => {
// set up a DOM element as a render target
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
// cleanup on exiting
document.body.removeChild(container);
container = null;
});
function TestComponent() {
const text = useUserSearch();
return <div>{text}</div>;
}
test("should mock userSearch", async () => {
const mockValue = "Im being mocked";
jest
.spyOn(useUserSearchMutation, "default")
.mockImplementation(() => () => mockValue);
act(() => {
render(<TestComponent />, container);
});
expect(container.textContent).toBe(mockValue);
});