为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

白衣染霜花 2021-04-12 16:18:54
我正在尝试模拟将数据检索到组件中的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.jsconst UserTable = () => {  const [users, setUsers] = useState([]);  useEffect(() => {    getTableData();  }, []);  const getTableData = () => {    new Promise((res, rej) => res(getRoles()))      .then(roles => getUsersWithRoles(roles))      .then(users => {        setUsers(users);      });  };  return (...)};
查看完整描述

3 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

默认情况下,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);

...并将模拟的响应添加到空的模拟函数。


查看完整回答
反对 回复 2021-04-29
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

这是一个广义的答案。首先,jest.mock(../service)在测试中执行。

然后转到您的服务文件,在其中进行呼叫。创建一个__mocks__文件,然后在内部创建一个与您的服务文件相同的文件。

然后为需要的每个服务创建函数,这些函数可以解析承诺,以便像常规调用一样异步。

const getUser = () => promise.resolve()

以上是一般示例。如果您需要数据,请使用功能创建一个您自己选择的模拟数据对象/数组并为其提供服务。


查看完整回答
反对 回复 2021-04-29
  • 3 回答
  • 0 关注
  • 252 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信