Enzyme - How to access and set <input> value?

天大地大妈咪最大 提交于 2019-11-27 11:02:21

问题


I'm confused about how to access <input> value when using mount. Here's what I've got as my 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();
  });

The console prints out undefined. But if I slightly modify the code, it works:

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

Except, of course, the input.simulate line fails since I'm using render now. I need both to work properly. How do I fix this?

EDIT:

I should mention, <EditableText /> is not a controlled component. But when I pass defaultValue into <input />, it seems to set the value. The second code block above does print out the value, and likewise if I inspect the input element in Chrome and type $0.value in the console, it shows the expected value.


回答1:


I think what you want is:

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

Here's my source.

You shouldn't need to use render() anywhere to set the value. And just FYI, you are using two different render()'s. The one in your first code block is from Enzyme, and is a method on the wraper object mount and find give you. The second one, though it's not 100% clear, is probably the one from react-dom. If you're using Enzyme, just use shallow or mount as appropriate and there's no need for render from react-dom.




回答2:


With Enzyme 3, if you need to change an input value but don't need to fire the onChange function you can just do this (node property has been removed):

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

You can use wrapper.find('input').simulate("change", { target: { value: "foo" }}) to invoke onChange if you have a prop for that (ie, for controlled components).




回答3:


Got it. (updated/improved version)

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



回答4:


So lots of different opinions here. The only thing that worked for me was none of the above, it was using input.props().value. I hope that helps.




回答5:


I am using create-react-app which comes with jest by default and enzyme 2.7.0.

This worked for me:

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:


None of the above worked for me. This is what worked for me on Enzyme ^3.1.1:

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

Here is the rest of the code for context:

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:


This works for me using enzyme 2.4.1:

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

console.log(input.node.value);



回答8:


here is my 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)

I have update my DOM with componentname.update() And then checking submit button validation(disable/enable) with length 10 digit.




回答9:


In case anyone is struggling, I found the following working for me

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

It seems that you need to define what happens in the change event first and then simulate it (instead of simulating the change event with data)




回答10:


In my case i was using ref callbacks,

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

To obtain the value. So enzyme will not change the value of this._username.

So i had to:

login.node._username.value = "mario@com.com";
    user.simulate('change');
    expect(login.state('mailValid')).toBe(true);

To be able to set the value then call change . And then assert.




回答11:


This worked for me:

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



回答12:


I use Wrapper's setValue[https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value] method to set value.

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



回答13:


.simulate() doesn't work for me somehow, I got it working with just accessing the node.value without needing to call .simulate(); in your case:

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

Hope this helps for others!



来源:https://stackoverflow.com/questions/37219772/enzyme-how-to-access-and-set-input-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!