无法使用 ReactDOM 渲染 React 函数

Unable to render React function using ReactDOM

我正在尝试为 Connect 4 React 页面的渲染函数 Game() 编写测试。

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";

import * as useGame from "./hooks/use-game";
import Game from ".";

const STATE_SPY = jest.spyOn(useGame, "default");
STATE_SPY.mockReturnValue({
  winner: "",
  dimensions: {
    numRows: 4,
    numCols: 4,
  },
  squares: [
    ["", "", "", ""],
    ["", "", "", ""],
    ["", "", "", ""],
    ["", "", "", ""],
  ],
});
const { container } = render(<Game />, document.getElementById("game"));


当我 运行 使用 npm test 进行测试时,我得到 Target container is not a DOM element.

如果我围绕错误创建一个元素,我会得到一个不同的错误:

const { container } = render(<Game />, document.createElement("div"));

TypeError: Cannot destructure property 'container' of '(0 , _reactDom.render)(...)' as it is null.

知道我需要如何正确编写这个 render() 函数吗?我已经在 Internet 上搜索过了,但似乎我已经以非常标准的方式进行了设置。

这是被测试的代码:

import React from "react";

import { useGame } from "./hooks";
import { Board, Settings } from "./components";
import { DARK_SYMBOL, LIGHT_SYMBOL, UseStyles } from "styles/styles";
import { dimensionsFormInput } from "types/form-inputs";

const INIT_ROW = 6;
const INIT_COL = 7;

// Game keeps track of the active player and winners of the Connect Four game
export default function Game(): JSX.Element {
  const {
    dimensions,
    setDimensions,
    squares,
    darkIsNext,
    winner,
    handleSquareClick,
  } = useGame(INIT_ROW, INIT_COL);
  const classes = UseStyles();

  return (
    <div id="game">
      <Board
        squares={squares}
        onClick={(row: number, col: number) => handleSquareClick(row, col)}
        winner={winner}
      />
      <span className={classes.blueText}>
        {winner.length > 0
          ? "Winner is " + winner
          : "Next piece: ".concat(darkIsNext ? DARK_SYMBOL : LIGHT_SYMBOL)}
      </span>
      <Settings
        dimensions={dimensions}
        onSubmit={(data: dimensionsFormInput) => setDimensions(data)}
      />
    </div>
  );
}

这个输入正确吗? import Game from "." 我认为正确的是:import Game from "./"

我没有使用来自 ReactDOM 的 render,而是使用来自 1@testing-library/react` 的 render。这让我可以进行我想要的测试。

您是否尝试创建自己的渲染函数?像这样,根据您的需要调整该函数,并在您的测试中使用它:

import React from 'react';
import { render as rtlRender } from '@testing-library/react';
import ConnectedRouter from 'react-router-redux/ConnectedRouter';
import { Provider } from 'react-redux';
import ReduxConnectedIntlProvider from '../ReduxConnectedIntlProvider';
import ThemeContext from '../context/theme-context';
import { store } from '../store';
import theme from '../theme/theme';
import { createMemoryHistory } from 'history';

const render = (
  ui,
  {
    route = '/',
    history = createMemoryHistory({ initialEntries: [route] }),
    ...renderOptions
  } = {}
) => {
  const Wrapper = ({ children }) => {
    return (
      <Provider store={store}>
        <ReduxConnectedIntlProvider>
          <ThemeContext.Provider value={theme}>
            <ConnectedRouter history={history}>{children}</ConnectedRouter>
          </ThemeContext.Provider>
        </ReduxConnectedIntlProvider>
      </Provider>
    );
  };
  return { ...rtlRender(ui, { wrapper: Wrapper, ...renderOptions }), history };
};

// re-export everything
export * from '@testing-library/react';

// override render method
export { render };

ReduxConnectedIntlProvider 的代码:

import { connect } from 'react-redux';
import { IntlProvider } from 'react-intl';

function mapStateToProps(state) {
  const { language, messages } = state.intl;
  return { locale: language, key: language, messages };
}

export default connect(mapStateToProps)(IntlProvider);

此致。