web-dev-qa-db-fra.com

Enzyme - Comment accéder et définir la valeur <input>?

Je ne comprends pas comment accéder à la valeur <input> avec mount. Voici ce que j'ai comme test:

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

La console affiche undefined. Mais si je modifie légèrement le code, cela fonctionne:

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

Sauf que, bien sûr, la ligne input.simulate échoue puisque j'utilise maintenant render. J'ai besoin des deux pour fonctionner correctement. Comment puis-je réparer ça?

MODIFIER:

Je devrais mentionner, <EditableText /> n'est pas un composant contrôlé. Mais lorsque je passe defaultValue dans <input />, il semble que la valeur soit définie. Le deuxième bloc de code ci-dessus affiche la valeur. De même, si j'inspecte l'élément d'entrée dans Chrome et que je sais $0.value dans la console, il indique la valeur attendue.

46
ffxsam

Je l'ai. (version mise à jour/améliorée)

  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();
  });
25
ffxsam

Je pense que ce que tu veux c'est:

input.simulate('change', { target: { value: 'Hello' } })

Voici ma source .

Vous ne devriez pas avoir besoin d'utiliser render() n'importe où pour définir la valeur. Et juste pour votre information, vous utilisez deux noms de render() différents. Celle de votre premier bloc de code provient d'Enzyme et constitue une méthode de l'objet wrapper que mount et find vous donnent. Le second, bien que ce ne soit pas clair à 100%, est probablement celui de react-dom. Si vous utilisez Enzyme, utilisez simplement shallow ou mount selon vos besoins et vous n'avez pas besoin de render à partir de react-dom.

45
Tyler Collier

Avec Enzyme 3, vous pouvez le faire si vous devez modifier une valeur d'entrée sans avoir à activer la fonction onChange (propriété nodea été supprimée ):

wrapper.find('input').instance().value = "foo";

Vous pouvez utiliser wrapper.find('input').simulate("change", { target: { value: "foo" }}) pour appeler onChange si vous avez un accessoire pour cela (c'est-à-dire pour les composants contrôlés).

24
bjudson

Donc, beaucoup d'opinions différentes ici. La seule chose qui a fonctionné pour moi n'était rien de ce qui précède, il utilisait input.props().value. J'espère que ça aide.

4
Y2H

J'utilise create-react-app, qui vient avec Jest par défaut et l'enzyme 2.7.0.

Cela a fonctionné pour moi:

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();
3
erika_dike

Aucun de ce qui précède n'a fonctionné pour moi. C'est ce qui a fonctionné pour moi sur Enzyme ^ 3.1.1:

input.instance().props.onChange(({ target: { value: '19:00' } }));

Voici le reste du code pour le contexte:

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

Cela fonctionne pour moi en utilisant l'enzyme 2.4.1:

const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');

console.log(input.node.value);
1
SunshinyDoyle

J'utilise la méthode setValue [ https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value] de Wrapper pour définir la valeur.

inputA = wrapper.findAll('input').at(0)
inputA.setValue('123456')
0
Calvin

voici mon code ..

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)

J'ai mis à jour mon DOM avec componentname.update() Et puis en vérifiant la validation du bouton d'envoi (disable/enable) avec une longueur de 10 chiffres.

0
Anupam Maurya

Dans mon cas, j'utilisais des rappels de références, 

  <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}}
                                                    >

Pour obtenir la valeur . Donc, enzyme ne changera pas la valeur de this._username.

Donc je devais:

login.node._username.value = "[email protected]";
    user.simulate('change');
    expect(login.state('mailValid')).toBe(true);

Pour pouvoir définir la valeur, appelez change. Et puis affirmer.

0
cabaji99

Cela a fonctionné pour moi:

let wrapped = mount(<Component />);
expect(wrapped.find("input").get(0).props.value).toEqual("something");
0

.simulate() ne fonctionne pas pour moi d'une certaine manière, je l'ai obtenu en accédant simplement au node.value sans avoir à appeler .simulate(); dans ton cas:

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

J'espère que cela aide pour les autres!

0
Jee Mok