Jest 测试使用新版本 18 创建 React APP index.js
Jest test Create React APP index.js with new version 18
我有这个 index.js 用于 React 版本 <= 17。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './views/App';
import reportWebVitals from './reportWebVitals';
import './assets/scss/app.scss';
import { BrowserRouter } from "react-router-dom";
import { Provider } from 'react-redux';
import store from "./store/index";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
这是测试:
import React from "react";
import ReactDOM from "react-dom";
import App from "../views/App";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import store from "../store/index";
jest.mock("react-dom", () => ({ render: jest.fn() }));
describe('Test index.js', () => {
it("Should render app without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require('../index.js');
expect(ReactDOM.render).toHaveBeenCalledWith(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>,
div
);
});
});
现在,对于版本 18,我需要将 ReactDOM.render 迁移到 createRoot
:
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './views/App';
import reportWebVitals from './reportWebVitals';
import './assets/scss/app.scss';
import { BrowserRouter } from "react-router-dom";
import { Provider } from 'react-redux';
import store from "./store/index";
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
但难的是考试
我试过
import React from "react";
import { createRoot } from 'react-dom/client';
import App from "../views/App";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import store from "../store/index";
describe('Test index.js', () => {
it("Should render app without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require('../index.js');
expect(root.render).toHaveBeenCalledWith(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
});
});
但是我进了shell
Test index.js
✕ Should render app without crashing (10 ms)
● Test index.js › Should render app without crashing
expect(received).toHaveBeenCalledWith(...expected)
Matcher error: received value must be a mock or spy function
Received has value: undefined
13 | document.body.appendChild(div);
14 | require('../index.js');
> 15 | expect(root.render).toHaveBeenCalledWith(
| ^
16 | <React.StrictMode>
17 | <BrowserRouter>
18 | <Provider store={store}>
at Object.<anonymous> (src/__tests__/index.test.js:15:25)
我确实也尝试在 describe
之前添加 jest.mock("react-dom/client");
[...]
jest.mock("react-dom/client");
describe('Test index.js', () => {
[...]
但是我明白了
Test index.js
✕ Should render app without crashing (6 ms)
● Test index.js › Should render app without crashing
TypeError: Cannot read properties of undefined (reading 'render')
10 | const container = document.getElementById('root');
11 | const root = createRoot(container);
> 12 | root.render(
| ^
13 | <React.StrictMode>
14 | <BrowserRouter>
15 | <Provider store={store}>
at Object.<anonymous> (src/index.js:12:6)
at Object.<anonymous> (src/__tests__/index.test.js:17:5)
如何为新 index.js 编写测试?
最后我解决了:
import index from "../index";
describe('Test index.js', () => {
it("Should render app without crashing", () => {
expect(
JSON.stringify(
Object.assign({}, index, { _reactInternalInstance: 'censored' }),
),
).toMatchSnapshot();
});
});
这是修改后的 index.js
文件:
const container = document.getElementById('root') || document.createElement('div');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
我有这个 index.js 用于 React 版本 <= 17。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './views/App';
import reportWebVitals from './reportWebVitals';
import './assets/scss/app.scss';
import { BrowserRouter } from "react-router-dom";
import { Provider } from 'react-redux';
import store from "./store/index";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
这是测试:
import React from "react";
import ReactDOM from "react-dom";
import App from "../views/App";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import store from "../store/index";
jest.mock("react-dom", () => ({ render: jest.fn() }));
describe('Test index.js', () => {
it("Should render app without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require('../index.js');
expect(ReactDOM.render).toHaveBeenCalledWith(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>,
div
);
});
});
现在,对于版本 18,我需要将 ReactDOM.render 迁移到 createRoot
:
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './views/App';
import reportWebVitals from './reportWebVitals';
import './assets/scss/app.scss';
import { BrowserRouter } from "react-router-dom";
import { Provider } from 'react-redux';
import store from "./store/index";
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
但难的是考试
我试过
import React from "react";
import { createRoot } from 'react-dom/client';
import App from "../views/App";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import store from "../store/index";
describe('Test index.js', () => {
it("Should render app without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require('../index.js');
expect(root.render).toHaveBeenCalledWith(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);
});
});
但是我进了shell
Test index.js
✕ Should render app without crashing (10 ms)
● Test index.js › Should render app without crashing
expect(received).toHaveBeenCalledWith(...expected)
Matcher error: received value must be a mock or spy function
Received has value: undefined
13 | document.body.appendChild(div);
14 | require('../index.js');
> 15 | expect(root.render).toHaveBeenCalledWith(
| ^
16 | <React.StrictMode>
17 | <BrowserRouter>
18 | <Provider store={store}>
at Object.<anonymous> (src/__tests__/index.test.js:15:25)
我确实也尝试在 describe
jest.mock("react-dom/client");
[...]
jest.mock("react-dom/client");
describe('Test index.js', () => {
[...]
但是我明白了
Test index.js
✕ Should render app without crashing (6 ms)
● Test index.js › Should render app without crashing
TypeError: Cannot read properties of undefined (reading 'render')
10 | const container = document.getElementById('root');
11 | const root = createRoot(container);
> 12 | root.render(
| ^
13 | <React.StrictMode>
14 | <BrowserRouter>
15 | <Provider store={store}>
at Object.<anonymous> (src/index.js:12:6)
at Object.<anonymous> (src/__tests__/index.test.js:17:5)
如何为新 index.js 编写测试?
最后我解决了:
import index from "../index";
describe('Test index.js', () => {
it("Should render app without crashing", () => {
expect(
JSON.stringify(
Object.assign({}, index, { _reactInternalInstance: 'censored' }),
),
).toMatchSnapshot();
});
});
这是修改后的 index.js
文件:
const container = document.getElementById('root') || document.createElement('div');
const root = createRoot(container);
root.render(
<React.StrictMode>
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>
</React.StrictMode>
);