Jest.js 测试使用React Query的简单组件

6mzjoqzu  于 2023-04-27  发布在  Jest
关注(0)|答案(2)|浏览(245)

我该如何为以下内容编写一个通过测试?其中getLifestages是一个有效的get API调用,它返回一个数组,如:
[{_id: 1, title: 'School'},{_id: 2, title: 'Work'}]

import { useQuery } from 'react-query';

const useLifestages = () => useQuery(
    ['GET_LIFESTAGES'],
    getLifestages,
    {
        staleTime: params.staleTime,
        keepPreviousData: true
    }
);

const LandingScreen = () => {
  const { data: lifestages, isLoading } = useLifestages();

  if (isLoading) return <Loading />

  return (
    <ErrorBoundary>
      <div className="container">
        <header className="header">
          Heading
        </header>
        <input 
          className="search-bar" 
          type='search' 
          role='search' 
        />
        
        {lifestages.map(lifestage => (
          <div
            key={lifestage._id}
            lifestage={lifestage} 
            role='button'
          />
        ))}

      </div>
    </ErrorBoundary>
  );
};

我想模拟API响应,到目前为止我所做的还没有工作。

jest.mock('react-query', () => ({
  useQuery: jest.fn().mockReturnValue(({ 
     data: [{
         _id: 1, title: 'School'
       },{
         _id: 2, title: 'Work'
     }], 
     isLoading: false
}));

describe("Load landing screen", () => {
  
    it("Renders the buttons", () => {
       render(
         <LandingScreen />
       );
       const button = screen.getByRole('button');
       expect(button).toBeInTheDocument();
    })

});

我看到的错误是这样的:

TypeError: Cannot destructure property 'data' of '(0 , _queries.useLifestages)(...)' as it is undefined.

       8 |
       9 |
    > 10 |   const { data: lifestages, isLoading } = useLifestages();

在我看来,这可能是因为数据还没有从调用中返回,并且给出了undefined。但是很明显,我的mock不起作用,因为它根本不应该调用API,而是使用我的mocked数据。我有点困惑,因为我是测试异步代码的新手,所以任何帮助都将非常感谢!

gzszwxb4

gzszwxb41#

我遇到了一个类似的错误,我所做的不是使用一个mock,而是监视ReactQuery;就像这样:

jest
      .spyOn(ReactQuery, 'useQuery')
      .mockImplementation(
        jest
          .fn()
          .mockReturnValue({ data: { ...SomeMockData }, isLoading: false, isSuccess: true, isError: false })
      )

希望能帮上忙。

blmhpbnm

blmhpbnm2#

jest.mock('react-query', () => ({
  useQuery: jest.fn().mockReturnValue(({ 
     data: [{
         _id: 1, title: 'School'
       },{
         _id: 2, title: 'Work'
     }], 
     isLoading: false
}));

这模拟了整个react-query库,只给了它一个useQuery钩子。我想这不会起作用,因为其他重要部分都没有了。这就像模拟了React,只给了它一个useEffect钩子...
我认为你最好不要模仿第三方库,而是模仿你所控制的,这是QueryFunction的实现方式,或者只是模仿网络层。
模拟网络层是文档(例如使用nock)和我的博客(例如使用msw)中推荐的内容
模拟网络层的优点是,您不仅可以测试useQuery返回data时组件是否正常工作,还可以测试如果它返回loading状态会发生什么。通过模拟useQuery,此实现将通过测试:

function LandingScreen() {
  const data = useQuery(...)
  
  return query.data.map(...)
}

但它肯定会在运行时死亡。

相关问题