微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Mock Service Worker 在自定义钩子中模拟获取?

如何解决如何使用 Mock Service Worker 在自定义钩子中模拟获取?

我想测试我的应用程序,该应用程序让用户输入一个查询,该查询向 Google Books API 发送请求,然后显示响应。

我已将数据获取逻辑分离到其自己的自定义挂钩中。我想用 Mock Service Worker 来模拟 fetch。我在运行测试时收到一个无效的钩子调用

Invalid hook call. Hooks can only be called inside of the body of a function component. This Could happen for one of the following reasons:
    1. You might have mismatching versions of React and the renderer (such as React DOM)
    2. You might be breaking the Rules of Hooks
    3. You might have more than one copy of React in the same app
    See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

      3 |
      4 | export const useBooksFetch = (initialUrl,initialData) => {
    > 5 |   const [url,setUrl] = useState(initialUrl);
        |                         ^
      6 |   const [data,setData] = useState(initialData);
      7 |   const [isLoading,setIsLoading] = useState(false);
      8 |   const [isError,setIsError] = useState(false);

      at resolvedispatcher (node_modules/react/cjs/react.development.js:1476:13)
      at useState (node_modules/react/cjs/react.development.js:1507:20)
      at useBooksFetch (src/hooks/useBooksFetch/useBooksFetch.js:5:25)
      at Object.<anonymous> (src/hooks/useBooksFetch/useBooksFetch.test.js:78:24)

  console.warn
    [MSW] Found a redundant usage of query parameters in the request handler URL for "GET https://www.googleapis.com/books/v1/volumes?q=travel". Please match against a path instead,and access query parameters in the response resolver function:
    
    rest.get("/books/v1/volumes",(req,res,ctx) => {
      const query = req.url.searchParams
      const q = query.get("q")
    })      

      4 |
      5 | const server = setupServer(
    > 6 |   rest.get(
        |        ^
      7 |     "https://www.googleapis.com/books/v1/volumes?q=travel",8 |     (req,ctx) => {
      9 |       return res(

确认

  • 在运行 npm ls react-domnpm ls react 时确认匹配的 React 版本,并返回 react-dom@17.0.2react@17.0.2
  • 未在类组件、事件处理程序、useMemo、useReducer 或 useEffect 中调用

我做错了什么? CodeSandbox

// useBooksFetch.js
export const useBooksFetch = (initialUrl,initialData) => {
  const [url,setUrl] = useState(initialUrl);
  const [data,setData] = useState(initialData);
  const [isLoading,setIsLoading] = useState(false);
  const [isError,setIsError] = useState(false);

  useEffect(() => {
    const fetchBooks = async () => {
      setIsError(false);
      setIsLoading(true);
      try {
        const result = await axios(url);
        setData(result.data);
      } catch (isError) {
        setIsError(true);
      }
      setIsLoading(false);
    };
    fetchBooks();
  },[url]);

  return [{ data,isLoading,isError },setUrl];
};


// useBooksFetch.test.js
const server = setupServer(
  rest.get(
    "https://www.googleapis.com/books/v1/volumes?q=travel",ctx) => {
      return res(
        ctx.status(200),ctx.json({
          data: {
            items: [
              {
                volumeInfo: {
                  title: "Travels"
                }
              },{
                volumeInfo: {
                  title: "The Travel Book"
                }
              },{
                volumeInfo: {
                  title: "Two arabic Travel Books"
                }
              },{
                volumeInfo: {
                  title: "Around India in 80 Trains"
                }
              },{
                volumeInfo: {
                  title: "World Travel"
                }
              },{
                volumeInfo: {
                  title:
                    "The ‘Book’ of Travels: Genre,Ethnology,and Pilgrimage,1250-1700"
                }
              },{
                volumeInfo: {
                  title: "The Impossible Collection of Chinese Art"
                }
              },{
                volumeInfo: {
                  title: "Travel Home"
                }
              },{
                volumeInfo: {
                  title: "Maximum City"
                }
              },{
                volumeInfo: {
                  title: "The Art of Travel"
                }
              }
            ]
          }
        })
      );
    }
  )
);

beforeAll(() => server.listen());
afterall(() => server.close());
afterEach(() => server.resetHandlers());

it("fetches successfully",async () => {
  const result = await useBooksFetch();
  expect(result.data).toHaveLength(10);
});

解决方法

错误是对的,你不能在组件之外使用钩子。

例如使用这个库 https://github.com/testing-library/react-hooks-testing-library

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。