Не в состоянии издеваться над функцией внутри useEffect

#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 @Marcus

3. Покажите код о 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);
});