我正在尝试学习React组件中的酶+笑话测试,并且在酶中使用.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,我可以将酶选择器写为div.className
。我以为我们可以将Enzyme选择器编写为JQuery选择器。因此,我使用了button.btn-primary
或button.btn btn-primary
,但是它不起作用。
但是,如果我使用.find('Button')
可以找到它。它显示了一个错误,它发现了2个节点,因为组件中有2个Button。这是否意味着.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);
});
组件-ExerciseAdd.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。如果您使用的是传统的Button html来呈现按钮,那么它将起作用。
有很多方法可以满足此要求。
方法1
console.log(component.debug());
是分析酶如何渲染和查看组件的关键实用工具。
component.find("Button").at(0).simulate('click')
,如Matt所述。
但是,您无法移动按钮的位置/添加新按钮,测试将失败。
方法2
component.find('Button[color="primary"]').simulate('click');
或
component.find('Button').find({ color: 'primary' }).simulate('click');
您可以使用上述代码找到具有任何属性/属性的右键。通过使用这些,您的测试代码不会耦合到组件的实现。您无需再担心按钮的位置。话虽如此,如果您有2个带有“主要”按钮的按钮,则需要寻找另一种唯一识别按钮的方法。
答案 0 :(得分:1)
由于您仅shallow
个安装,因此它将是Button.btn-primary
或Button.btn.btn-primary
。您可以通过在console.log(component.debug());
测试内部编写it
来确认这一点,并且它将打印出DOM
结构,如enzyme
所见。
如果需要,还可以将.find()
概括为component.find("Button").at(0).simulate('click')
或用外行的术语“在位置0找到Button组件并模拟点击”。或者简单地component.find(".btn-primary").simulate('click')
。找到DOM元素有很多选择,并且它成为个人喜好(尽管,我更希望使用更具体的选择器,尤其是如果您曾经mount
一个组件)。
请注意,请注意广义进口:
如果import WorkoutAdd from '../workoutAdd';
位于同一文件夹中,则可以解析为workAdd.test.js
而不是workoutAdd.js
。因此,如果您遇到开玩笑陈述expected a string (for built-in components) or a class/function (for composite components)
的问题,那么您就会知道原因。