Enzyme wrapper.update()导致引用输入不再具有值prop

问题描述 投票:2回答:1

这里是一个代码沙箱,其中包含一个模拟此问题的测试。如以下问题中所述,此代码沙箱中的测试失败:https://codesandbox.io/s/react-jest-and-enzyme-testing-c7vng


我正在尝试测试在<input />内部更新的useEffect的值。这是代码沙箱中的代码,它是我在项目中尝试做的事情的简化版本。

import React, { useEffect, useRef, useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    ref.current.value = "";
    console.log(typeof ref.current.value);
  }, [count]);

  const ref = useRef(null);

  const handleClick = () => {
    setCount(count + 1);
    console.log(count);
  };

  return (
    <div>
      <input ref={ref} type="text" />
      <button onClick={handleClick}>click me</button>
    </div>
  );
};

export default App;

我使用useRef设置<input />的值。

单击useEffect时将调用<button /><button />更新useState countuseEffect正在观看count的更新,并且被称为副作用。

useEffect中,我将ref.current.value设置为一个空字符串,然后将typeof这个值记录下来以验证它是一个字符串。

在测试中,我尝试模拟这种行为:

describe("App", () => {
  const wrapper = mount(<App />);
  wrapper.find("input").props().value = "hello";
  act(() =>
    wrapper
      .find("button")
      .props()
      .onClick()
  );
  console.log(wrapper.find("input").debug());
  wrapper.update();
  console.log(wrapper.find("input").debug());
  expect(wrapper.find("input").length).toBe(1);
  expect(wrapper.find("input").props().value).toBe("hello");
});

我将value属性设置为'hello'。然后,我调用<button /> onClick道具,并有效地单击它。然后,我调用wrapper.update(),并且在debug()之前和之后也将<input />记录为update()

update()之前,<input />具有包含value'hello'道具。在update()之后,<input />没有value属性。这会导致测试失败,表示更新后<input /> value未定义。

更新后输入的值不是''吗?

javascript reactjs jestjs enzyme
1个回答
0
投票

以下是当前方式的问题列表:

  • [<input ref={ref} type="text" />描述一个React Element,没有值prop

  • 属性值应通过状态控制,而不是直接变异

    wrapper.find("input").props().value = "hello";
    
  • 在DOM节点上设置值与设置prop值不同。使用React意味着您要对它进行DOM操作。当传递useRef的初始值时,null允许访问基础DOM节点,并且尽管App状态,此下一行仍会更改DOM。

    ref.current.value = "";
    

在某些情况下,尽管处于App状态,但还是很方便地操作DOM。然后,测试应处理DOM节点并对其进行更改。

describe("App", () => {
  const wrapper = mount(<App />);
  wrapper.find("input").getDOMNode().value = "hello";
  act(() =>
    wrapper
      .find("button")
      .props()
      .onClick()
  );
  wrapper.update();
  expect(wrapper.find("input").length).toBe(1);
  expect(wrapper.find("input").getDOMNode().value).toBe("");
});
© www.soinside.com 2019 - 2024. All rights reserved.