我正在尝试学习 React 组件中的 Enzyme + Jest 测试,但我在使用 Enzyme 中的 .find
方法时遇到错误。
错误
Method “simulate” is meant to be run on 1 node. 0 found instead.
19 | onAddNew={onAddNew} />);
20 |
> 21 | component.find('button.btn-primary').simulate('click');
| ^
22 | expect(onAddNew).toHaveBeenCalledTimes(1);
我检查了呈现的 html,我可以看到与我在 find 方法中写的完全一样的按钮和类名。
根据这个link ,我可以将 enzyme 选择器写成 div.className
。我认为我们可以将 Enzyme 选择器编写为 JQuery 选择器。因此,我使用了 button.btn-primary
或 button.btn btn-primary
,但它不起作用。
但是,如果我使用 .find('Button')
它可以找到它。它显示一个错误,它找到了 2 个节点,因为我在组件中有 2 个按钮。这是否意味着 .find
方法在 React Components 而不是渲染的 DOM 文档上执行搜索?如果是,我如何编写选择器来找到主按钮?有没有办法不用 first() 或 (0) 就可以找到它?
具体请看以下代码:
workoutAdd.test.js
import React from 'react';
import { shallow } from 'enzyme';
import WorkoutAdd from '../workoutAdd';
it('renders without crashing', () => {
const
onChange = jest.fn(),
onChangeDate = jest.fn(),
onAddNew = jest.fn(),
toggle = jest.fn(),
item = {};
const component = shallow(<WorkoutAdd
toggle={toggle}
modal={true}
item={item}
onChange={onChange}
onChangeDate={onChangeDate}
onAddNew={onAddNew} />);
component.find('button.btn-primary').simulate('click');
expect(onAddNew).toHaveBeenCalledTimes(1);
});
组件 - workoutAdd.js
import React, { Component } from 'react';
import {
Modal, ModalBody, ModalHeader, ModalFooter, Button
, Form, FormGroup, Label, Input
} from 'reactstrap';
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
export default class WorkoutAdd extends Component {
render() {
const {
modal,
toggle,
item,
onChange,
onChangeDate,
onAddNew } = this.props;
return (
<Modal isOpen={modal} toggle={toggle} centered>
<ModalHeader toggle={toggle}>Add New Workout</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<Label for="Date">Date</Label><br />
<DatePicker
name="date"
id="Date"
className="form-control"
selected={item.date}
onChange={onChangeDate}
dateFormat="dd/MM/yyyy"
maxDate={new Date()}
/>
</FormGroup>
<FormGroup>
<Label for="WorkoutType">Type</Label>
<Input
type="select"
name="workoutType"
onChange={onChange}
value={item.workoutType}
id="WorkoutType">
<option>Running</option>
<option>Cycling</option>
</Input>
</FormGroup>
<FormGroup>
<Label for="Calories">Calories</Label>
<Input
type="number"
name="calories"
id="Calories"
value={item.calories}
onChange={onChange}
placeholder="Calories burnt"
/>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={onAddNew}>Save</Button>{' '}
<Button color="secondary" onClick={toggle}>Cancel</Button>
</ModalFooter>
</Modal>
)
}
}
更新的答案
我在问题中使用的代码 (button.btn-primary
) 不起作用,因为我正在使用 Bootstrap 组件来呈现 Button。如果您使用传统的按钮 html 来呈现您的按钮,它会起作用。
有很多方法可以达到这个要求。
方法一
console.log(component.debug());
是分析 Enzyme 如何呈现和查看组件的关键实用程序。
component.find("Button").at(0).simulate('click')
如 Matt 所述。
但是,您不能移动按钮的位置/添加新按钮,测试将失败。
方法二
component.find('Button[color="primary"]').simulate('click');
或
component.find('Button').find({ color: 'primary' }).simulate('click');
您可以使用上面的代码找到具有任何属性/ Prop 的正确按钮。通过使用这些,您的测试代码不会耦合到组件的实现。您无需再担心按钮的位置。话虽如此,如果您有 2 个带有“primary”的按钮,您将需要找到另一种方法来唯一标识按钮。
最佳答案
因为您只是浅
安装,所以它应该是Button.btn-primary
或Button.btn.btn-primary
。您可以通过在 it
测试中写入 console.log(component.debug());
来确认这一点,它会打印出 DOM
结构如 enzyme
所见。
如果需要,您还可以将 .find()
概括为 component.find("Button").at(0).simulate('click')
或通俗地说“在位置 0 找到一个 Button 组件并模拟点击”。或者简单地 component.find(".btn-primary").simulate('click')
。您有多种选择来查找 DOM 元素,这成为个人偏好(尽管我更喜欢更具体的选择器,尤其是当您mount
组件时)。
作为旁注,请注意广义导入:
import WorkoutAdd from '../workoutAdd';
如果它们在同一个文件夹。因此,如果您遇到开 Jest 说 需要字符串(对于内置组件)或类/函数(对于复合组件)
的问题,那么您就会知道原因。
关于javascript - 如何使用 Enzyme React Test .find 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54504815/