Подтвердить что ты не робот

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 в консоли, он показывает ожидаемое значение.

4b9b3361

Ответ 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, вы можете просто сделать это (nodeproperty был удален):

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);

Чтобы установить значение, измените вызов. И затем утверждают.

Ответ 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

Надеюсь, это поможет другим!