【问题标题】:Jest & Enzyme test error with React Context APIReact Context API 的 Jest 和 Enzyme 测试错误
【发布时间】:2020-09-05 20:22:23
【问题描述】:

我正在使用 Jest & Enzyme 测试一个 React 应用程序。当我运行npm run test 时,我在UserContext.jsx 中得到错误,该错误是在MainPage.jsx 中导入的。我该如何解决?

错误信息

Invariant Violation:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用。这可能由于以下原因之一而发生: 1. React 和渲染器的版本可能不匹配(例如 React DOM) 2. 你可能违反了 Hooks 的规则 3. 你可能在同一个应用中拥有多个 React 副本

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

UserContext.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

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

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>
    );
}

【问题讨论】:

    标签: reactjs jestjs enzyme


    【解决方案1】:

    错误说明了问题所在:

    钩子只能在函数组件内部调用

    这里的钩子在组件外用错了:

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

    应该是 {context: someContext },但问题是 Enzyme 渲染器接受旧版 React 上下文的上下文,它不能特别影响上下文消费者和功能组件。

    目前shallow doesn't support context providers,需要使用mount

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

    由于useUserValue 位于自己的模块中,因此可以单独对其进行测试并在使用它的组件中进行模拟,这样它就可以与shallow 一起使用。

    如果 React 和 ReactDOM 有多个副本或版本不匹配,也会出现此错误,但情况并非如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-26
      • 2019-02-06
      • 2019-07-05
      • 2019-01-29
      • 1970-01-01
      • 2017-11-10
      • 2017-02-12
      • 2020-08-07
      相关资源
      最近更新 更多