酶 - 如何访问和设置<input />值?

时间:2016-05-13 21:43:53

标签: unit-testing reactjs enzyme

我对使用<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,它会显示预期值。

16 个答案:

答案 0 :(得分:52)

我认为你想要的是:

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

Here's my source

您无需在任何地方使用render()来设置值。仅供参考,您使用的是两个不同的render()。第一个代码块中的一个来自Enzyme,是包装器对象mountfind给你的方法。第二个,虽然不是100%明确,但可能来自react-dom。如果您使用的是Enzyme,请根据需要使用shallowmount,而render不需要react-dom

答案 1 :(得分:27)

知道了。 (更新/改进版)

  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 :(得分:26)

使用酶3 ,如果您需要更改输入值但不需要触发onChange函数,则可以执行此操作(node属性has been removed):

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

如果你有一个支柱(例如,对于受控组件),你可以使用wrapper.find('input').simulate("change", { target: { value: "foo" }})来调用onChange

答案 3 :(得分:7)

这里有很多不同的意见。对我来说唯一有用的不是上面的,而是使用input.props().value。我希望有所帮助。

答案 4 :(得分:3)

我正在使用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();

答案 5 :(得分:2)

以上都不适合我。这对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);

答案 6 :(得分:1)

这适用于我使用酶2.4.1:

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

console.log(input.node.value);

答案 7 :(得分:1)

这是我的代码。

at the top boi
Entering data_check
re-tweeting
done re-tweeting
off(this is me editing this just says the state of the command it did to my robot)
here in on_data now

我已用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 然后检查长度为10位数字的提交按钮验证(禁用/启用)。

答案 8 :(得分:1)

万一有人在挣扎,我发现以下对我有用

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

似乎您需要先定义更改事件中发生的事情,然后对其进行仿真(而不是使用数据模拟更改事件)

答案 9 :(得分:0)

在我的情况下,我使用了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);

为了能够设置值,然后调用更改。断言。

答案 10 :(得分:0)

我使用包装器的setValue [https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value]方法设置值。

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

答案 11 :(得分:0)

这对我有用:

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

答案 12 :(得分:0)

我正在使用TypeScript进行响应,以下代码对我有用

   Id MyProp MyPropRef
   -- ------ ---------
 3780   3780

直接设置值

Get-Process | Select-Object Id, 
    @{name="MyProp"; expression={$_.id}} | Select-Object *,
    @{name="MyPropRef"; expression={$_.MyProp}}

   Id MyProp MyPropRef
   -- ------ ---------
 3780   3780      3780

正在引起我一个编译警告。

答案 13 :(得分:0)

我用一种非常简单的方法解决了

  1. 通过道具设置值
  const wrapper: ShallowWrapper = shallow(<ProfileViewClass name: 'Sample Name' />);
  1. HTML代码
  <input type='text' defaultValue={props.name} className='edituser-name' />
  1. wrapper.find(element).props().attribute-name访问属性
  it('should render user name', () => {
    expect(wrapper.find('.edituser-name').props().defaultValue).toContain(props.name);
  });

欢呼

答案 14 :(得分:0)

以上所有解决方案都不适合我,因为我正在使用Formik,并且需要在更改字段值的同时将字段标记为“已触摸”。以下代码对我有用。

const emailField = orderPageWrapper.find('input[name="email"]')

emailField.simulate('focus')
emailField.simulate('change', { target: { value: 'test@example.com', name: 'email' } })
emailField.simulate('blur')

答案 15 :(得分:-1)

.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

希望这对其他人有帮助!