React JS ButtonAction组件单元测试不通过,document未定义如何解决?
问题修复方案
1. 解决document is not defined报错
该错误是因为Jest默认使用Node环境运行测试,不存在浏览器端的DOM对象,需切换到jsdom模拟浏览器环境:
- 若使用Jest 28及以上版本,先安装依赖:
npm install --save-dev jest-environment-jsdom - 配置测试环境,二选一即可:
- 在
jest.config.js配置文件中添加:testEnvironment: 'jsdom' - 在测试文件的第一行添加注释:
/** @jest-environment jsdom */
- 在
2. 修复组件逻辑缺陷
你的组件调用了onClose、onSave、onRemove三个回调props,还使用了disabled参数,未传参时会触发运行时报错,可以给组件添加默认props:
export default class ButtonAction extends Component { // 添加默认props static defaultProps = { disabled: false, onClose: () => {}, onSave: () => {}, onRemove: () => {} } // 此处保留你原有的render代码 render() { const { id, disabled, onClose, onSave, onRemove, isDelete } = this.props; return ( <div className="footer"> <div className="button-container"> <button data-testid="cancel" onClick={() => onClose()}> Cancel </button> { isDelete ? <button data-testid="remove" disabled={!disabled} onClick={() => onRemove()} className='primary'> Yes </button> : <button data-testid="save" disabled={!disabled} onClick={() => onSave()} className={disabled ? 'primary' : 'disabled'}> { id ? 'Update' : 'Save' } </button> } </div> </div> ) } }
3. 修复测试用例错误
第二个测试用例断言逻辑错误,你要校验的是删除模式下remove按钮的文本,而非cancel按钮,修改后的测试用例参考:
// 可复用的模拟函数 const mockCallback = jest.fn(); test("id exists", () => { const { getByTestId } = render(<ButtonAction id={''} isDelete={false} onClose={mockCallback} onSave={mockCallback} onRemove={mockCallback} />); expect(getByTestId('cancel')).toBeTruthy(); }); test("delete button exists", () => { const { getByTestId } = render(<ButtonAction id={'remove'} isDelete={true} onClose={mockCallback} onSave={mockCallback} onRemove={mockCallback} />); // 原错误:用了getByTestId('cancel'),改为getByTestId('remove') expect(getByTestId('remove').textContent).toBe(' Yes ') }); test('save button exists', () => { const { getByTestId } = render(<ButtonAction id={''} isDelete={false} onClose={mockCallback} onSave={mockCallback} onRemove={mockCallback} />) expect(getByTestId('save').textContent).toBe(' Save ') }) test('calling render with the same component on the same container does not remount', () => { const { getByTestId } = render(<ButtonAction id={'1'} isDelete={false} onClose={mockCallback} onSave={mockCallback} onRemove={mockCallback} />) expect(getByTestId('save').textContent).toBe(' Update ') })
可选优化:判断文本时可以用
textContent.trim()移除前后空格,避免组件内的换行、缩进空格导致断言失败。
内容的提问来源于stack exchange,提问作者Ms Designer
相关产品推荐
相关产品推荐

