测试一个 create-react-app index.js 文件
Test a create-react-app index.js file
我希望 100% 覆盖我的项目。
为此,我需要测试我的 index.js 文件,该文件非常基础:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(<App/>, document.getElementById('root'));
我找不到如何测试它。
创建函数时,例如 :
index.js
const index = (div) => {
ReactDOM.render(<App />, div || document.getElementById('root'));
};
然后测试它:
index.test.js
it('renders without crashing', () => {
const div = document.createElement('div');
index(div);
});
导入时出现错误 index
:
不变违规:_registerComponent(...):目标容器不是 DOM 元素。
PS:
请注意,我已经进行了以下测试,运行良好:
App.test.jsx
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App/>, div);
});
主要问题是你想在那里测试什么。如果您想测试 您的 代码是否正常工作,请编写一个监视 ReactDOM.render
并模拟 document.getElementById('root')
的单元测试。因为这就是您的所有代码,使用我们的 App 组件和特定的 div
.
调用 ReactDOM.render
import ReactDOM from 'react-dom';
...
jest.mock('react-dom', ()=> ({render: jest.fn()}))
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App/>, div);
global.document.getElementById = (id) => id ==='root' && div
expect(ReactDOM.render).toHaveBeenCalledWith(...)
});
如果您想测试该应用程序是否真的在您的页面中启动,您应该使用 Selenium 或 Nightwatch.js
编写集成测试
要获得 100% 的覆盖率,您也可以忽略此文件,方法是将其添加到您的 jest 设置中的 coveragePathIgnorePatterns
如果您的目标是项目的 100% 覆盖率并且 index.js
文件中的代码很简单,那么从覆盖率报告中排除该文件可能是一个不错的选择,正如 Andreas Köberle 指出的那样在他的回答中。
Create-react-app目前在Jest配置中只支持这四个key(source):
collectCoverageFrom
coverageReporters
coverageThreshold
snapshotSerializers
这就是为什么
coveragePathIgnorePatterns": ["src/index.js"]
不行。
将以下代码添加到 package.json
文件的最外层范围:
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
"!src/index.js"
]
}
在下图中,您可以看到测试 运行 的输出,此代码已添加到使用 create-react-app v1.4.3 创建的初始应用程序的 package.json
中。请注意,index.js
文件不再出现在报告中,也不会影响覆盖百分比。
我找到了一个 article online 解释这种编写测试的方式...
// index.test.js
import Index from './index.js';
it('renders without crashing', () => {
expect(JSON.stringify(
Object.assign({}, Index, { _reactInternalInstance: 'censored' })
)).toMatchSnapshot();
});
现在相应地更改 index.js 文件:
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
export default ReactDOM.render(
<App />,
document.getElementById('root') || document.createElement('div')
);
这就是我测试的方式index.js
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));
index.test.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
jest.mock("react-dom", () => ({ render: jest.fn() }));
describe("Application root", () => {
it("should render without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require("./index.js");
expect(ReactDOM.render).toHaveBeenCalledWith(<App />, div);
});
});
在 上进行扩展,以下是跳过 TypeScript 项目的这些琐碎文件的方法:
- 编辑
package.json
在根级别添加以下代码段
{
...rest of existing props,
"jest": {
"collectCoverageFrom": [
"src/**/*.{ts,tsx}",
"!src/serviceWorker.ts",
"!src/index.tsx"
]
}
}
保存并重新运行覆盖
现在覆盖率应该更高了。
这是我所做的,看起来效果非常完美(100% 覆盖率,应用程序不会中断):
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
export const ReactStrictMode = <React.StrictMode>
<App />
</React.StrictMode>
export const rootElement = document.getElementById('root')
ReactDOM.render(
ReactStrictMode,
rootElement
);
然后在 index.spec.js
:
// src/index.spec.js
/* eslint-env jest */
import React from 'react'
import ReactDOM from 'react-dom'
import { ReactStrictMode, rootElement } from './index'
jest.mock('react-dom', () => ({ render: jest.fn() }))
describe('index.js', () => {
it('renders without crashing', () => {
ReactDOM.render(ReactStrictMode, rootElement)
expect(ReactDOM.render).toHaveBeenCalledWith(ReactStrictMode, rootElement)
})
})
Added a couple of more test cases. Any feedback would be appreciated...
import React from "react";
import { render, cleanup } from "@testing-library/react";
import ReactDOM from "react-dom";
import App from "./App";
afterEach(cleanup);
// jest.mock will mock all the function using jest.fn() that is present inside the react-dom library
jest.mock("react-dom");
describe("Testing Application Root", () => {
it("should render without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require("./index");
expect(ReactDOM.render).toHaveBeenCalledWith(<App />, div);
});
it("should render the app inside div which has root id", () => {
expect(global.document.getElementById("root")).toBeDefined();
});
it("should render App component", () => {
expect(App).toBeDefined();
});
});
我希望 100% 覆盖我的项目。
为此,我需要测试我的 index.js 文件,该文件非常基础:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(<App/>, document.getElementById('root'));
我找不到如何测试它。 创建函数时,例如 :
index.js
const index = (div) => {
ReactDOM.render(<App />, div || document.getElementById('root'));
};
然后测试它:
index.test.js
it('renders without crashing', () => {
const div = document.createElement('div');
index(div);
});
导入时出现错误 index
:
不变违规:_registerComponent(...):目标容器不是 DOM 元素。
PS:
请注意,我已经进行了以下测试,运行良好:
App.test.jsx
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App/>, div);
});
主要问题是你想在那里测试什么。如果您想测试 您的 代码是否正常工作,请编写一个监视 ReactDOM.render
并模拟 document.getElementById('root')
的单元测试。因为这就是您的所有代码,使用我们的 App 组件和特定的 div
.
ReactDOM.render
import ReactDOM from 'react-dom';
...
jest.mock('react-dom', ()=> ({render: jest.fn()}))
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App/>, div);
global.document.getElementById = (id) => id ==='root' && div
expect(ReactDOM.render).toHaveBeenCalledWith(...)
});
如果您想测试该应用程序是否真的在您的页面中启动,您应该使用 Selenium 或 Nightwatch.js
编写集成测试要获得 100% 的覆盖率,您也可以忽略此文件,方法是将其添加到您的 jest 设置中的 coveragePathIgnorePatterns
如果您的目标是项目的 100% 覆盖率并且 index.js
文件中的代码很简单,那么从覆盖率报告中排除该文件可能是一个不错的选择,正如 Andreas Köberle 指出的那样在他的回答中。
Create-react-app目前在Jest配置中只支持这四个key(source):
collectCoverageFrom
coverageReporters
coverageThreshold
snapshotSerializers
这就是为什么
coveragePathIgnorePatterns": ["src/index.js"]
不行。
将以下代码添加到 package.json
文件的最外层范围:
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
"!src/index.js"
]
}
在下图中,您可以看到测试 运行 的输出,此代码已添加到使用 create-react-app v1.4.3 创建的初始应用程序的 package.json
中。请注意,index.js
文件不再出现在报告中,也不会影响覆盖百分比。
我找到了一个 article online 解释这种编写测试的方式...
// index.test.js
import Index from './index.js';
it('renders without crashing', () => {
expect(JSON.stringify(
Object.assign({}, Index, { _reactInternalInstance: 'censored' })
)).toMatchSnapshot();
});
现在相应地更改 index.js 文件:
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
export default ReactDOM.render(
<App />,
document.getElementById('root') || document.createElement('div')
);
这就是我测试的方式index.js
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));
index.test.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
jest.mock("react-dom", () => ({ render: jest.fn() }));
describe("Application root", () => {
it("should render without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require("./index.js");
expect(ReactDOM.render).toHaveBeenCalledWith(<App />, div);
});
});
在
- 编辑
package.json
在根级别添加以下代码段
{ ...rest of existing props, "jest": { "collectCoverageFrom": [ "src/**/*.{ts,tsx}", "!src/serviceWorker.ts", "!src/index.tsx" ] } }
保存并重新运行覆盖
现在覆盖率应该更高了。
这是我所做的,看起来效果非常完美(100% 覆盖率,应用程序不会中断):
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
export const ReactStrictMode = <React.StrictMode>
<App />
</React.StrictMode>
export const rootElement = document.getElementById('root')
ReactDOM.render(
ReactStrictMode,
rootElement
);
然后在 index.spec.js
:
// src/index.spec.js
/* eslint-env jest */
import React from 'react'
import ReactDOM from 'react-dom'
import { ReactStrictMode, rootElement } from './index'
jest.mock('react-dom', () => ({ render: jest.fn() }))
describe('index.js', () => {
it('renders without crashing', () => {
ReactDOM.render(ReactStrictMode, rootElement)
expect(ReactDOM.render).toHaveBeenCalledWith(ReactStrictMode, rootElement)
})
})
Added a couple of more test cases. Any feedback would be appreciated...
import React from "react";
import { render, cleanup } from "@testing-library/react";
import ReactDOM from "react-dom";
import App from "./App";
afterEach(cleanup);
// jest.mock will mock all the function using jest.fn() that is present inside the react-dom library
jest.mock("react-dom");
describe("Testing Application Root", () => {
it("should render without crashing", () => {
const div = document.createElement("div");
div.id = "root";
document.body.appendChild(div);
require("./index");
expect(ReactDOM.render).toHaveBeenCalledWith(<App />, div);
});
it("should render the app inside div which has root id", () => {
expect(global.document.getElementById("root")).toBeDefined();
});
it("should render App component", () => {
expect(App).toBeDefined();
});
});