reactjs - "TypeError: react.useContext is not a function"使用 React 测试库模拟上下文提供程序时

标签 reactjs jestjs mocking react-testing-library react-context

我正在尝试确定在使用 React Context 进行 Jest 测试时如何最好地模拟提供者。我发现的最有希望的线索是 RTL,它在他们的文档中提供了以下示例:https://testing-library.com/docs/example-react-context
我一直在尝试多种结构,但即使我密切关注他们的例子,我也会收到上述错误。
在这里,我在测试我的 Dialog 组件时几乎完全按照他们的示例进行操作:
Jest 测试

import React from 'react';
import { render } from '@testing-library/react';
import { DialogContext, defaultState } from '../../../../store/contexts/dialogContext';

const customRender = (ui, { providerProps, ...renderOptions }) => {
  return render(
    <DialogContext.Provider {...providerProps}>{ui}</DialogContext.Provider>,
    renderOptions
  );
};

it('Dialog should work', async () => {
  const providerProps = {
    dialogType: 'CANCEL',
    ...defaultState,
  };
  const { container } = customRender(<Dialog />, { providerProps });
  const results = await axe(container);

  expect(results).toHaveNoViolations();
});

对话框组件
import React, { useContext } from 'react';
import { DialogContext } from '../../../store/contexts/dialogContext';

export default function Dialog() {
  const [dialogState, dialogDispatch] = useContext(DialogContext);

  //logic

 return (
  <div id='dialog'/>
  );
}
这是我的 Dialog 组件的简化版本,但是一旦它在第 2 行调用 useContext(),我就会收到以下错误。
Error: Uncaught [TypeError: (0 , _react.useContext) is not a function or its return value is not iterable]
由于“React”在相关文件的范围内,并且我正在密切关注 RTL 示例,因此我很难过。欢迎提供模拟提供者的其他方式的解决方案或建议。
编辑:为清楚起见,添加 dialogContext 文件。当不在 Jest 流程中时,组件和上下文工作正常。
import React, { createContext, useReducer } from 'react';
import { dialogReducer } from '../reducers/dialogReducer';

export const DialogContext = createContext({});
const { Provider } = DialogContext;

export const defaultState = {
  //state object
}

export const DialogProvider = ({ children }) => {
  const [state, reducer] = useReducer(dialogReducer, defaultState);

  return <Provider value={[state, reducer]}>{children}</Provider>
}
当 DialogContext 从 Dialog 组件(前一行)中记录时,它看起来像预期的那样:
{ '$$typeof': Symbol(react.context),
        _calculateChangedBits: null,
        _currentValue: undefined,
        _currentValue2: {},
        _threadCount: 0,
        Provider: { '$$typeof': Symbol(react.provider), _context: [Circular] },
        Consumer:
         { '$$typeof': Symbol(react.context),
           _context: [Circular],
           _calculateChangedBits: null },
        _currentRenderer: {},
        _currentRenderer2: null }

最佳答案

错误 is ambiguous并且可能真正发生在 useContext 时未定义,当 useContext是一个函数,但不返回可迭代(数组)。
如果 Jest 配置不正确并且 react 可能会发生第一种情况包作为 CommonJS 模块导入,并转换为 ES 模块 default通过模块互操作导入。
第二种情况是对错误最简单的解释。上下文提供程序未提供数组值,因此 useContext不返回数组。除非 defaultState对象包含 value具有数组值的属性,...defaultState传播将导致错误的提供者值(value)。
提供者值应在测试中以与在应用程序中相同的方式提供:

<Provider value={[state, reducer]}>...
如果打算不使用 dialogReducer在测试中,可以提供一个 spy :
<DialogContext.Provider value={[defaultState, mockedDispach]}>...
否则 DialogProvider可以用来代替 DialogContext.Provider因为它已经提供了预期的提供者值(value)。

关于reactjs - "TypeError: react.useContext is not a function"使用 React 测试库模拟上下文提供程序时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64081681/

相关文章:

reactjs - react Hook : memoize click handlers for list?

javascript - Div 滚动结束检测无法一致工作

jestjs - 为什么nestjs单元测试在beforeEach而不是beforeAll中创建测试模块?

react-native - jest react-native 和 bugsnag 有这样的问题

file-upload - 如何在 Jest 中模拟文件上传或文件对象?

.net - rhino-mocks - 很好的示例应用程序

javascript - 使用 React 管理无限滚动表中的复选框状态

reactjs - 将 React 组件注入(inject) HTML

unit-testing - 我在单元测试中做错了什么吗?

java - 仅出于测试目的模拟 Web 服务