酶 - 如何访问和设置 <input> 值?
Enzyme - How to access and set <input> value?
我对使用 mount
时如何访问 <input>
值感到困惑。这是我的测试结果:
it('cancels changes when user presses esc', done => {
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.render().attr('value'));
input.simulate('focus');
done();
});
控制台打印出undefined
。但是如果我稍微修改一下代码,它就可以工作了:
it('cancels changes when user presses esc', done => {
const wrapper = render(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.val());
input.simulate('focus');
done();
});
当然,除了 input.simulate
行失败,因为我现在正在使用 render
。我需要两者才能正常工作。我该如何解决这个问题?
编辑:
我应该提一下,<EditableText />
不是受控组件。但是当我将 defaultValue
传递给 <input />
时,它似乎设置了值。上面的第二个代码块确实打印出值,同样,如果我检查 Chrome 中的输入元素并在控制台中键入 [=21=].value
,它会显示预期值。
知道了。 (updated/improved 版本)
it('cancels changes when user presses esc', done => {
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
input.simulate('focus');
input.simulate('change', { target: { value: 'Changed' } });
input.simulate('keyDown', {
which: 27,
target: {
blur() {
// Needed since <EditableText /> calls target.blur()
input.simulate('blur');
},
},
});
expect(input.get(0).value).to.equal('Hello');
done();
});
我想你想要的是:
input.simulate('change', { target: { value: 'Hello' } })
您不需要在任何地方使用 render()
来设置值。仅供参考,您使用的是两个不同的 render()
。您的第一个代码块中的那个来自 Enzyme,并且是包装对象 mount
和 find
给您的一个方法。第二个,虽然不是 100% 清楚,但可能是来自 react-dom
的那个。如果您使用的是 Enzyme,请根据需要使用 shallow
或 mount
,不需要 react-dom
.
中的 render
在我的例子中,我使用了 ref 回调,
<input id="usuario" className="form-control" placeholder="Usuario"
name="usuario" type="usuario"
onKeyUp={this._validateMail.bind(this)}
onChange={()=> this._validateMail()}
ref={(val) =>{ this._username = val}}
>
获取值。
所以酶不会改变this._username.
的值
所以我不得不:
login.node._username.value = "mario@com.com";
user.simulate('change');
expect(login.state('mailValid')).toBe(true);
为了能够设置值然后调用 change 。然后断言。
这对我使用酶 2.4.1 有效:
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.node.value);
我正在使用 create-react-app 默认情况下带有 jest 和 enzyme 2.7.0.
这对我有用:
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input')[index]; // where index is the position of the input field of interest
input.node.value = 'Change';
input.simulate('change', input);
done();
使用 Enzyme 3,如果您需要更改输入值但不需要触发 onChange
函数,您可以这样做(node
属性 has been removed):
wrapper.find('input').instance().value = "foo";
您可以使用 wrapper.find('input').simulate("change", { target: { value: "foo" }})
来调用 onChange
如果您有相应的道具(即,对于受控组件)。
这里有很多不同的意见。唯一对我有用的是上面的none,它使用的是input.props().value
。希望对您有所帮助。
以上的 None 对我有用。这就是我在 Enzyme ^3.1.1 上的工作方式:
input.instance().props.onChange(({ target: { value: '19:00' } }));
这是上下文的其余代码:
const fakeHandleChangeValues = jest.fn();
const fakeErrors = {
errors: [{
timePeriod: opHoursData[0].timePeriod,
values: [{
errorIndex: 2,
errorTime: '19:00',
}],
}],
state: true,
};
const wrapper = mount(<AccessibleUI
handleChangeValues={fakeHandleChangeValues}
opHoursData={opHoursData}
translations={translationsForRendering}
/>);
const input = wrapper.find('#input-2').at(0);
input.instance().props.onChange(({ target: { value: '19:00' } }));
expect(wrapper.state().error).toEqual(fakeErrors);
我使用 Wrapper 的 setValue[https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value] 方法设置值。
inputA = wrapper.findAll('input').at(0)
inputA.setValue('123456')
.simulate()
不知何故对我不起作用,我只需要访问 node.value
就可以使用它而无需调用 .simulate()
;在你的情况下:
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input').at(0);
// Get the value
console.log(input.node.value); // Hello
// Set the value
input.node.value = 'new value';
// Get the value
console.log(input.node.value); // new value
希望这对其他人有帮助!
这是我的代码..
const input = MobileNumberComponent.find('input')
// when
input.props().onChange({target: {
id: 'mobile-no',
value: '1234567900'
}});
MobileNumberComponent.update()
const Footer = (loginComponent.find('Footer'))
expect(Footer.find('Buttons').props().disabled).equals(false)
我已将 DOM 更新为 componentname.update()
然后检查长度为 10 位的提交按钮验证(disable/enable)。
这对我有用:
let wrapped = mount(<Component />);
expect(wrapped.find("input").get(0).props.value).toEqual("something");
如果有人遇到困难,我发现以下对我有用
const wrapper = mount(<NewTask {...props} />); // component under test
const textField = wrapper.find(TextField);
textField.props().onChange({ target: { value: 'New Task 2' } })
textField.simulate('change');
// wrapper.update() didn't work for me, need to find element again
console.log(wrapper.find(TextField).props()); // New Task 2
看来需要先定义change事件发生了什么,然后再模拟(而不是用数据模拟change事件)
我正在使用 React with TypeScript,以下对我有用
wrapper.find('input').getDOMNode<HTMLInputElement>().value = 'Hello';
wrapper.find('input').simulate('change');
直接设置值
wrapper.find('input').instance().value = 'Hello'`
给我一个编译警告。
我用很简单的方法解决了:
- 设置道具的价值:
const wrapper: ShallowWrapper = shallow(<ProfileViewClass name: 'Sample Name' />);
- Html代码:
<input type='text' defaultValue={props.name} className='edituser-name' />
- 从
wrapper.find(element).props().attribute-name
: 访问属性
it('should render user name', () => {
expect(wrapper.find('.edituser-name').props().defaultValue).toContain(props.name);
});
干杯
None 上面的解决方案对我有用,因为我使用的是 Formik,我需要在更改字段值的同时将字段标记为“已触及”。以下代码对我有用。
const emailField = orderPageWrapper.find('input[name="email"]')
emailField.simulate('focus')
emailField.simulate('change', { target: { value: 'test@example.com', name: 'email' } })
emailField.simulate('blur')
我对使用 mount
时如何访问 <input>
值感到困惑。这是我的测试结果:
it('cancels changes when user presses esc', done => {
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.render().attr('value'));
input.simulate('focus');
done();
});
控制台打印出undefined
。但是如果我稍微修改一下代码,它就可以工作了:
it('cancels changes when user presses esc', done => {
const wrapper = render(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.val());
input.simulate('focus');
done();
});
当然,除了 input.simulate
行失败,因为我现在正在使用 render
。我需要两者才能正常工作。我该如何解决这个问题?
编辑:
我应该提一下,<EditableText />
不是受控组件。但是当我将 defaultValue
传递给 <input />
时,它似乎设置了值。上面的第二个代码块确实打印出值,同样,如果我检查 Chrome 中的输入元素并在控制台中键入 [=21=].value
,它会显示预期值。
知道了。 (updated/improved 版本)
it('cancels changes when user presses esc', done => {
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
input.simulate('focus');
input.simulate('change', { target: { value: 'Changed' } });
input.simulate('keyDown', {
which: 27,
target: {
blur() {
// Needed since <EditableText /> calls target.blur()
input.simulate('blur');
},
},
});
expect(input.get(0).value).to.equal('Hello');
done();
});
我想你想要的是:
input.simulate('change', { target: { value: 'Hello' } })
您不需要在任何地方使用 render()
来设置值。仅供参考,您使用的是两个不同的 render()
。您的第一个代码块中的那个来自 Enzyme,并且是包装对象 mount
和 find
给您的一个方法。第二个,虽然不是 100% 清楚,但可能是来自 react-dom
的那个。如果您使用的是 Enzyme,请根据需要使用 shallow
或 mount
,不需要 react-dom
.
render
在我的例子中,我使用了 ref 回调,
<input id="usuario" className="form-control" placeholder="Usuario"
name="usuario" type="usuario"
onKeyUp={this._validateMail.bind(this)}
onChange={()=> this._validateMail()}
ref={(val) =>{ this._username = val}}
>
获取值。 所以酶不会改变this._username.
的值所以我不得不:
login.node._username.value = "mario@com.com";
user.simulate('change');
expect(login.state('mailValid')).toBe(true);
为了能够设置值然后调用 change 。然后断言。
这对我使用酶 2.4.1 有效:
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.node.value);
我正在使用 create-react-app 默认情况下带有 jest 和 enzyme 2.7.0.
这对我有用:
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input')[index]; // where index is the position of the input field of interest
input.node.value = 'Change';
input.simulate('change', input);
done();
使用 Enzyme 3,如果您需要更改输入值但不需要触发 onChange
函数,您可以这样做(node
属性 has been removed):
wrapper.find('input').instance().value = "foo";
您可以使用 wrapper.find('input').simulate("change", { target: { value: "foo" }})
来调用 onChange
如果您有相应的道具(即,对于受控组件)。
这里有很多不同的意见。唯一对我有用的是上面的none,它使用的是input.props().value
。希望对您有所帮助。
None 对我有用。这就是我在 Enzyme ^3.1.1 上的工作方式:
input.instance().props.onChange(({ target: { value: '19:00' } }));
这是上下文的其余代码:
const fakeHandleChangeValues = jest.fn();
const fakeErrors = {
errors: [{
timePeriod: opHoursData[0].timePeriod,
values: [{
errorIndex: 2,
errorTime: '19:00',
}],
}],
state: true,
};
const wrapper = mount(<AccessibleUI
handleChangeValues={fakeHandleChangeValues}
opHoursData={opHoursData}
translations={translationsForRendering}
/>);
const input = wrapper.find('#input-2').at(0);
input.instance().props.onChange(({ target: { value: '19:00' } }));
expect(wrapper.state().error).toEqual(fakeErrors);
我使用 Wrapper 的 setValue[https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value] 方法设置值。
inputA = wrapper.findAll('input').at(0)
inputA.setValue('123456')
.simulate()
不知何故对我不起作用,我只需要访问 node.value
就可以使用它而无需调用 .simulate()
;在你的情况下:
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input').at(0);
// Get the value
console.log(input.node.value); // Hello
// Set the value
input.node.value = 'new value';
// Get the value
console.log(input.node.value); // new value
希望这对其他人有帮助!
这是我的代码..
const input = MobileNumberComponent.find('input')
// when
input.props().onChange({target: {
id: 'mobile-no',
value: '1234567900'
}});
MobileNumberComponent.update()
const Footer = (loginComponent.find('Footer'))
expect(Footer.find('Buttons').props().disabled).equals(false)
我已将 DOM 更新为 componentname.update()
然后检查长度为 10 位的提交按钮验证(disable/enable)。
这对我有用:
let wrapped = mount(<Component />);
expect(wrapped.find("input").get(0).props.value).toEqual("something");
如果有人遇到困难,我发现以下对我有用
const wrapper = mount(<NewTask {...props} />); // component under test
const textField = wrapper.find(TextField);
textField.props().onChange({ target: { value: 'New Task 2' } })
textField.simulate('change');
// wrapper.update() didn't work for me, need to find element again
console.log(wrapper.find(TextField).props()); // New Task 2
看来需要先定义change事件发生了什么,然后再模拟(而不是用数据模拟change事件)
我正在使用 React with TypeScript,以下对我有用
wrapper.find('input').getDOMNode<HTMLInputElement>().value = 'Hello';
wrapper.find('input').simulate('change');
直接设置值
wrapper.find('input').instance().value = 'Hello'`
给我一个编译警告。
我用很简单的方法解决了:
- 设置道具的价值:
const wrapper: ShallowWrapper = shallow(<ProfileViewClass name: 'Sample Name' />);
- Html代码:
<input type='text' defaultValue={props.name} className='edituser-name' />
- 从
wrapper.find(element).props().attribute-name
: 访问属性
it('should render user name', () => {
expect(wrapper.find('.edituser-name').props().defaultValue).toContain(props.name);
});
干杯
None 上面的解决方案对我有用,因为我使用的是 Formik,我需要在更改字段值的同时将字段标记为“已触及”。以下代码对我有用。
const emailField = orderPageWrapper.find('input[name="email"]')
emailField.simulate('focus')
emailField.simulate('change', { target: { value: 'test@example.com', name: 'email' } })
emailField.simulate('blur')