用玩笑和React-Testing-Library测试React上下文

时间:2019-04-14 00:46:03

标签: reactjs unit-testing jestjs react-hooks react-context

我正在尝试为我的component App.js设置测试,该测试接受context作为道具并返回提供者。问题是当我尝试对其进行测试时,我传递给它的上下文始终会解析为未定义。

我在组件中放了一个控制台日志,在创建上下文和创建组件(应该将上下文作为参数)之间放置一个控制台日志。由于某种原因,这首先导致了该组件中的console.log。这可能就是为什么我得到上下文未定义的原因,因为它尚未初始化。

// Component/Provider
const App = (props) => {
  const {children, context} = props;
  const {data, dispatch} = useReducer(reducer);
  console.log(context); //undefined and this console.log runs first
  return <context.Provider value={useCallback(dispatch)}>{children}</context.Provider>
}

在我的test.js中

import React, {useContext} from 'react';
import {render} from 'react-testing-library';
import {App} from './App';
const context = React.createContext();

function Provider(children) {
  console.log(context); //Is correct but runs second
  return <App Context={context}>{children}</App>;
}

const customRender = (ui, options) =>
  render(ui, { wrapper: Provider, ...options });

const Consumer = () => {
  const dispatch = useContext(context);
  returns <Button onClick={dispatch({type: 'Do something'})}>Whatever</Button/>;
}
customRender(<Consumer />)

我应该能够将Context传递到我的组件中以创建提供程序,但是它始终是未定义的。

2 个答案:

答案 0 :(得分:0)

也许这是一个错字,但是您的文件真的叫test.js吗? 如果是这样,您将需要将其更改为.jsx,因为您正在测试中使用JSX(例如,在Provider组件中)。

答案 1 :(得分:0)

在了解如何进行操作之前,我被卡住了一段时间。我的问题是我没有为上下文创建正确的形状:我给它提供了一些道具,但没有给在我的真实上下文中传递的道具。因此该组件无法浏览该新形状。

这是我的产品形状(未经测试)

export default React.createContext({
  authenticationInfos: {
    isAuthenticated: false,
    user: {
      id: "",
      email: "",
      roles: []
    },
    customer: {
      id: "",
      prenom: "",
      nom: "",
      tel: "",
      adress: "",
      postalCode: "",
      town: "",
      sellRequests: []
    }
  },
  setAuthenticationInfos: value => {}
});

我只是传递了 authenticationInfos 内部的内容,而不传递了道具 authenticationInfos 本身,而且我也忘记了 setAuthenticationInfos 道具。

这是我的与上下文挂钩一起工作的测试组件:

react-testing-library文档中的功能

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

describe("<ConnectModal>", () => {
  test("should be able to access auth context", () => {
    const providerProps = {
      authenticationInfos: {
        isAuthenticated: false,
        user: {
          id: "",
          email: "",
          roles: [],
        },
        customer: {
          id: "",
          prenom: "",
          nom: "",
          tel: "",
          adress: "",
          postalCode: "",
          town: "",
          sellRequests: [],
        },
        shop: {
          appToken: 54,
        },
      },
      setAuthenticationInfos: (value) => {},
    };
    customRender(<MKMConnectModal />, { providerProps });
    // expect(screen.getByText(/^My Name Is:/)).toHaveTextContent(
    //   "My Name Is: C3P0"
    // );
  });
});