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

IT技术 unit-testing reactjs enzyme
2021-04-14 17:01:41

我对<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在控制台中键入,它会显示预期值。

6个回答

我想你想要的是:

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

这是我的来源

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

嗨,我使用默认值,如问题this.state = {inputNum: 10};,而收到的永远是1虽然预计是100在集input.simulate('change', { target: { value: '100' } })有人可以帮忙吗?
2021-05-31 17:01:41
input.render()react-dom渲染。是这样的:airbnb.io/enzyme/docs/api/ShallowWrapper/render.html
2021-06-11 17:01:41
我应该更清楚。我的意思是渲染看起来像render(<EditableText defaultValue="Hello" />). 我认为你的用例比我想象的更专业;我看到它仅处理设置输入值但具有焦点和“取消更改”的注意事项。如果你能创造一个plunker 那就太好了
2021-06-13 17:01:41
此外,shallow()由于某种原因不起作用..该focus事件触发了一个尝试引用的方法this.refs.input,该方法失败了。但是当我换出shallowmount,它按预期工作。大多数..(模拟ESC键的另一个问题)
2021-06-20 17:01:41
@nambk 最好提出一个新问题。也许这与'100'. 我不确定 10 和 1 的差异。
2021-06-21 17:01:41

使用Enzyme 3,如果您需要更改输入值但不需要触发onChange函数,您可以这样做(node属性已被删除):

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

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

instance()如果通过mount.
2021-05-23 17:01:41
NOTE: can only be called on a wrapper instance that is also the root instance.- 来自airbnb.io/enzyme/docs/api/ShallowWrapper/instance.html 上的文档
2021-05-27 17:01:41
顺便说一句,如果您使用的是 MUI,它是相同的,带有 TextFields Select 等等(您应该调用“本机”元素而不是 MUI 元素)
2021-06-16 17:01:41

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

  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();
  });
@Siddharth_Vyas 试试 input.prop('value')
2021-05-31 17:01:41
@Pre101 我实际上开始使用 Jest 而不是 Enzyme。强烈推荐!
2021-06-06 17:01:41
@ffxsam : input.get(0).value 总是显示“undefined”
2021-06-12 17:01:41
好奇这对你有什么作用。我们使用 PhantomJS 并且mount()不会将组件插入到 DOM 中。因此,他们无法获得焦点。我们必须添加一个 DOM 元素并使用context选项mount()
2021-06-15 17:01:41

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

值得注意的是,您还可以使用:input.prop('value')如果您知道道具键的名称。
2021-06-19 17:01:41
这是唯一允许我询问输入值的答案。
2021-06-20 17:01:41

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