简体   繁体   English

React Context API 的 Jest & Enzyme 测试错误

[英]Jest & Enzyme test error with React Context API

I am testing a React app with Jest & Enzyme.我正在使用 Jest 和 Enzyme 测试 React 应用程序。 When I run npm run test I get the error in UserContext.jsx that is imported in MainPage.jsx .当我运行npm run test我在MainPage.jsx导入的UserContext.jsx中收到错误。 How can I fix that?我该如何解决?

Error message错误信息

Invariant Violation: Invalid hook call.不变违规:无效的钩子调用。 Hooks can only be called inside of the body of a function component.钩子只能在函数组件的主体内部调用。 This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app这可能是由于以下原因之一而发生的: 1. 你的 React 和渲染器的版本可能不匹配(例如 React DOM) 2. 你可能违反了 Hooks 规则 3. 你可能有多个 React 副本同一个应用

      11 | };
      12 | 
    > 13 | export const useUserValue = () => useContext(UserContext);
         |                                   ^

UserContext.jsx用户上下文.jsx

import React, {createContext, useContext, useReducer} from "react";

export const UserContext = createContext();

export const UserProvider = ({reducer, initialState, children}) => {
    return(
        <UserContext.Provider value={useReducer(reducer, initialState)}>
            {children}
        </UserContext.Provider>
    )
};

export const useUserValue = () => useContext(UserContext);

MainPage.test.js主页.test.js

import React from 'react';
import 'jest-styled-components';

import { configure, shallow, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import MainPage from "./MainPage";
import {useUserValue} from "../Context/UserContext";

configure({adapter: new Adapter()});

describe('Main Page Component', () => {

    it('exists', () => {
        const wrapper = shallow(<MainPage />, {context: useUserValue()});
        expect(wrapper).toMatchSnapshot();
    });
});

MainPage.jsx主页.jsx

import React, {useEffect, useState} from 'react';
import {useUserValue} from "../Context/UserContext";

export default function MainPage(props) {
    const [{ user }, dispatch] = useUserValue();

    return (
        <React.Fragment>
           {user.name}
        </React.Fragment>
    );
}

The error says what is the problem:错误说明是什么问题:

Hooks can only be called inside of the body of a function component Hooks 只能在函数组件内部调用

Here the hook is incorrectly used outside the component:这里钩子在组件外被错误使用:

const wrapper = shallow(<MainPage />, {context: useUserValue()});

It should have been {context: someContext } , but the problem is that Enzyme renderer accepts a context for legacy React context that cannot affect context consumers and functional components in particular.它应该是{context: someContext } ,但问题是 Enzyme 渲染器接受遗留 React 上下文的上下文,该上下文不能特别影响上下文使用者和功能组件。

Currently shallow doesn't support context providers and needs to use mount :目前shallow不支持上下文提供者,需要使用mount

const wrapper = mount(
 <UserContext.Provider value={...}>
   <MainPage />
 </UserContext.Provider>
);

Since useUserValue is located in its own module, it could be tested separately and mocked in components where it's used, this way it can be used with shallow .由于useUserValue位于其自己的模块中,因此可以单独测试并在使用它的组件中模拟它,这样它就可以与shallow一起使用。

This error can also occur if there are multiple copies or mismatching versions of React and ReactDOM, but this is not the case.如果 React 和 ReactDOM 存在多个副本或版本不匹配,也会出现此错误,但事实并非如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM