Я не понимаю, как получить доступ к <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
в консоли, он показывает ожидаемое значение.
источник
input.render()
неreact-dom
рендеринг. Это так: airbnb.io/enzyme/docs/api/ShallowWrapper/render.htmlshallow()
по какой-то причине не работает ...focus
событие запускает метод, который пытается ссылатьсяthis.refs.input
, но не работает. Но когда я меняюshallow
наmount
, он работает, как ожидалось. В основном .. (еще одна проблема с имитацией клавиши ESC)render(<EditableText defaultValue="Hello" />)
. Я думаю, что ваш вариант использования более специализирован, чем я думал; Я вижу, что это касается только установки входного значения, но с фокусом и «отменой изменений». Было бы здорово, если бы можно было сделать плункер .С Enzyme 3 , если вам нужно изменить входное значение, но не нужно запускать
onChange
функцию, вы можете просто сделать это (node
свойство было удалено ):wrapper.find('input').instance().value = "foo";
Вы можете использовать
wrapper.find('input').simulate("change", { target: { value: "foo" }})
для вызова,onChange
если у вас есть опора для этого (например, для управляемых компонентов).источник
NOTE: can only be called on a wrapper instance that is also the root instance.
- из документации на airbnb.io/enzyme/docs/api/ShallowWrapper/instance.htmlinstance()
может быть вызван для любой дочерней оболочки, если она была отрисована черезmount
.Понял. (обновленная / улучшенная версия)
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(); });
источник
mount()
не вставляем компоненты в DOM. Итак, они не могут получить фокус. Мы должны добавить элемент DOM и использоватьcontext
опцию дляmount()
input.prop('value')
Так что здесь много разных мнений. Единственное, что у меня сработало, это ничего из вышеперечисленного, я использовал
input.props().value
. Надеюсь, это поможет.источник
input.prop('value')
если вы знаете имя своего проп-ключа.Я использую приложение create-react-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();
источник
У меня ничего из вышеперечисленного не сработало. Вот что у меня сработало на 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);
источник
Я использую реакцию с TypeScript, и у меня сработало следующее:
wrapper.find('input').getDOMNode<HTMLInputElement>().value = 'Hello'; wrapper.find('input').simulate('change');
Установка значения напрямую
wrapper.find('input').instance().value = 'Hello'`
вызывал у меня предупреждение о компиляции.
источник
У меня это работает с использованием фермента 2.4.1:
const wrapper = mount(<EditableText defaultValue="Hello" />); const input = wrapper.find('input'); console.log(input.node.value);
источник
console.log
копался в (под) свойствах объекта, чтобы получить то, что мне нужно. При этом я часто использовал.node
в той или иной форме, как и вы. Однако я не припомню,.node
чтобы упоминалось в какой-либо официальной документации, предполагающей, что он может меняться / прерываться между выпусками, поскольку он официально не является частью публично рекламируемого API. Кроме того, часто кажется, что есть альтернативы. напримерinput.node.value
===input.get(0).value
. Таким образом, это.node
может сработать, и я подозреваю, что иногда это дает хороший взлом, но используйте его с осторожностью.вот мой код ..
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 цифр.источник
В моем случае я использовал обратные вызовы 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. А потом утверждать.
источник
Это сработало для меня:
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
Кажется, вам нужно сначала определить, что происходит в событии изменения, а затем смоделировать его (вместо моделирования события изменения с данными)
источник
Решил очень просто:
const wrapper: ShallowWrapper = shallow(<ProfileViewClass name: 'Sample Name' />);
<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); });
Ура
источник
Ни одно из вышеперечисленных решений не помогло мне, потому что я использовал Formik, и мне нужно было отметить поле «затронутым» вместе с изменением значения поля. Для меня работал следующий код.
const emailField = orderPageWrapper.find('input[name="email"]') emailField.simulate('focus') emailField.simulate('change', { target: { value: 'test@example.com', name: 'email' } }) emailField.simulate('blur')
источник
Я использую метод 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
Надеюсь, это поможет другим!
источник
.node
, чтобы использовать.instance()
или.getDOMNode()
, зависит от того, использовали ли вы результат как ReactElement или DOMComponent.