如何在React应用程序中使用Jest通过useQuery模拟axios

bjp0bcyl  于 2023-03-06  发布在  Jest
关注(0)|答案(2)|浏览(174)

我有一个compomcomponent,在这个组件中,我调用后端服务并接收数据:

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

export const Products = () => {
  const { isLoading, data } = useQuery({
    queryKey: ['products'],
    queryFn: () =>
      axios.get(`${process.env.REACT_APP_BASE_URL}/client/products`).then((res) => res.data)
  });
...

但是当我尝试创建一个单元测试时:

test('products shown on page', () => {
  render(<Products />);
});

我得到这个错误:

SyntaxError: Cannot use import statement outside a module

      3 | import { Product } from '../../components/Product';
      4 | import { useQuery } from '@tanstack/react-query';
    > 5 | import axios from 'axios';
        | ^

我已经尝试使用jest.mock(axios)jest.spyOn(@tanstack/react-query, 'useQuery'),但错误仍然显示,请帮助我解决这个问题的权利。

z31licg0

z31licg01#

您看到的错误与Jest默认不支持ES6 import语句有关,要解决这个问题,您可以使用Babel将代码转换为Jest可以理解的ES 5语法。
要使用Jest配置Babel,您需要安装以下软件包:

npm install --save-dev @babel/core @babel/preset-env babel-jest

然后,在项目的根目录下创建一个babel.config.js文件,并添加以下代码:

module.exports = {
  presets: ['@babel/preset-env']
};

接下来,您需要更新package.json中的Jest配置以使用Babel:

"jest": {
  "transform": {
    "^.+\\.jsx?$": "babel-jest"
  }
}

现在,Jest将在运行测试之前使用Babel来翻译您的代码。
要从@tanstack/react-query模拟useQuery钩子,可以使用jest.mock,如下所示:

jest.mock('@tanstack/react-query', () => ({
  useQuery: jest.fn(() => ({ isLoading: false, data: [] }))
}));

这将模拟useQuery钩子,使其始终返回isLoading设置为false的对象和数据的空数组。
要模拟axios,可以使用jest.mock,如下所示:

jest.mock('axios', () => ({
  get: jest.fn(() => Promise.resolve({ data: [] }))
}));

这将模拟axios.get函数总是返回解析为空数据数组的对象的承诺。
把所有这些放在一起,你的测试文件应该看起来像这样:

import { render } from '@testing-library/react';
import { Products } from './Products';
import axios from 'axios';

jest.mock('@tanstack/react-query', () => ({
  useQuery: jest.fn(() => ({ isLoading: false, data: [] }))
}));

jest.mock('axios', () => ({
  get: jest.fn(() => Promise.resolve({ data: [] }))
}));

test('products shown on page', () => {
  render(<Products />);
});

进行这些更改后,测试应该会成功运行,而不会出现导入错误。

ukqbszuj

ukqbszuj2#

我回答没有试图执行任何代码,所以对不起,如果它确实工作。
您可以使用jest对象中的spyOn

import axios from 'axios';

test('products shown on page', () => {
  jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({data: ...}))
  render(<Products />);
})

现在你可以让axios.get返回你想在mockReturnValue中得到的任何东西。
确认mock不处理.then((res) => res.data)到您的queryFn匿名函数中的处理,因此它将在之后执行,这就是为什么我将... Package 到一个对象中,并将data作为属性。

相关问题