Enzyme - Как получить доступ и установить значение <input>?
Я смущен тем, как получить доступ к значению <input>
при использовании mount
. Вот что я получил в качестве теста:
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 и набираю $0.value
в консоли, он показывает ожидаемое значение.
Ответы
Ответ 1
Получил это. (обновленная/улучшенная версия)
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();
});
Ответ 2
Я думаю, что вы хотите:
input.simulate('change', { target: { value: 'Hello' } })
Здесь мой источник.
Вам не нужно использовать render()
где угодно, чтобы установить значение. И только FYI, вы используете два разных render()
. Один в вашем первом блоке кода - от Enzyme, и это метод на объекте wraper mount
и find
дает вам. Второй, хотя и не на 100% понятный, вероятно, один из react-dom
. Если вы используете Enzyme, просто используйте shallow
или mount
, если это необходимо, и нет необходимости render
от react-dom
.
Ответ 3
С Enzyme 3, если вам нужно изменить входное значение, но не нужно запускать функцию onChange
, вы можете просто сделать это (node
property был удален):
wrapper.find('input').instance().value = "foo";
Вы можете использовать wrapper.find('input').simulate("change", { target: { value: "foo" }})
для вызова onChange
, если у вас есть поддержка для этого (т.е. для контролируемых компонентов).
Ответ 4
Здесь много разных мнений. Единственное, что сработало для меня, не было ни в одном из них, оно использовало input.props().value
. Надеюсь, что это поможет.
Ответ 5
Я использую приложение create-response-app, которое поставляется с jest по умолчанию и энзимом 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();
Ответ 6
Ничто из вышеперечисленного не помогло мне. Вот что у меня сработало на Ферменте ^ 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);
Ответ 7
Это работает для меня с использованием фермента 2.4.1:
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.node.value);
Ответ 8
вот мой код..
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 цифр.
Ответ 9
В моем случае я использовал обратные вызовы 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 = "[email protected]";
user.simulate('change');
expect(login.state('mailValid')).toBe(true);
Чтобы установить значение, измените вызов. И затем утверждают.
Ответ 10
Я использую метод Wrapper setValue [ https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value] для установки значения.
inputA = wrapper.findAll('input').at(0)
inputA.setValue('123456')
Ответ 11
Это сработало для меня:
let wrapped = mount(<Component />);
expect(wrapped.find("input").get(0).props.value).toEqual("something");
Ответ 12
.simulate()
у меня как-то не работает, у меня все получилось, просто node.value
доступ к 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
Надеюсь, это поможет другим!