如何模拟正在使用Jest测试的React组件中进行的API调用

我正在尝试模拟将数据检索到组件中的fetch()。


我正在使用它作为模拟提取的模型,但是我无法使其正常工作。


运行测试时出现此错误: babel-plugin-jest-hoist: The module factory of 'jest.mock()' is not allowed to reference any out-of-scope variables.


有没有办法让这些函数返回模拟数据,而不是实际尝试进行真正的API调用?


代码

utils / getUsers.js

返回角色映射到每个用户的用户。


const getUsersWithRoles = rolesList =>

  fetch(`/users`, {

    credentials: "include"

  }).then(response =>

    response.json().then(d => {

      const newUsersWithRoles = d.result.map(user => ({

        ...user,

        roles: rolesList.filter(role => user.roles.indexOf(role.iden) !== -1)

      }));

      return newUsersWithRoles;

    })

  );

组件/UserTable.js

const UserTable = () => {

  const [users, setUsers] = useState([]);

  useEffect(() => {

    getTableData();

  }, []);


  const getTableData = () => {

    new Promise((res, rej) => res(getRoles()))

      .then(roles => getUsersWithRoles(roles))

      .then(users => {

        setUsers(users);

      });

  };

  return (...)

};


白衣染霜花
浏览 253回答 3
3回答

慕码人8056858

默认情况下,jest.mock呼叫被挂起babel-jest......这意味着它们先于测试文件中的其他任何文件运行,因此测试文件中声明的任何变量都将不在范围内。这就是为什么传递给的模块工厂jest.mock无法引用其自身之外的任何内容的原因。一种选择是像这样在模块工厂内部移动数据:jest.mock("../utils/userUtils", () => {  const users = [ /* mock users data */ ];  return {    getUsers: jest.fn(() => Promise.resolve(users))  };});jest.mock("../utils/roleUtils", () => {  const roles = [ /* mock roles data */ ];  const usersWithRoles = [ /* mock usersWithRoles data */ ];  return {    getRolesWithUsers: jest.fn(() => Promise.resolve(usersWithRoles)),    getRoles: jest.fn(() => Promise.resolve(roles))  };});另一种选择是使用jest.spyOn以下方法模拟功能:import * as userUtils from '../utils/userUtils';import * as roleUtils from '../utils/roleUtils';const users = [ /* mock users data */ ];const roles = [ /* mock roles data */ ];const usersWithRoles = [ /* mock usersWithRoles data */ ];const mockGetUsers = jest.spyOn(userUtils, 'getUsers');mockGetUsers.mockResolvedValue(users);const mockGetRolesWithUsers = jest.spyOn(roleUtils, 'getRolesWithUsers');mockGetRolesWithUsers.mockResolvedValue(usersWithRoles);const mockGetRoles = jest.spyOn(roleUtils, 'getRoles');mockGetRoles.mockResolvedValue(roles);另一种选择是自动模拟模块:import * as userUtils from '../utils/userUtils';import * as roleUtils from '../utils/roleUtils';jest.mock('../utils/userUtils');jest.mock('../utils/roleUtils');const users = [ /* mock users data */ ];const roles = [ /* mock roles data */ ];const usersWithRoles = [ /* mock usersWithRoles data */ ];userUtils.getUsers.mockResolvedValue(users);roleUtils.getRolesWithUsers.mockResolvedValue(usersWithRoles);roleUtils.getRoles.mockResolvedValue(roles);...并将模拟的响应添加到空的模拟函数。

一只甜甜圈

这是一个广义的答案。首先,jest.mock(../service)在测试中执行。然后转到您的服务文件,在其中进行呼叫。创建一个__mocks__文件,然后在内部创建一个与您的服务文件相同的文件。然后为需要的每个服务创建函数,这些函数可以解析承诺,以便像常规调用一样异步。const getUser = () => promise.resolve()以上是一般示例。如果您需要数据,请使用功能创建一个您自己选择的模拟数据对象/数组并为其提供服务。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript