【问题标题】:React, Enzyme: Testing a state update-Functional ComponentReact, Enzyme:测试状态更新功能组件
【发布时间】:2020-04-17 03:42:54
【问题描述】:

我很难理解如何正确触发可以验证的状态更新。基本上我有 2 个案例我正在尝试测试,它们仅与按钮的视觉状态有关。

1) 测试按钮是否在视觉上被选中 2) 测试按钮是否在视觉上被禁用

应用程序

 export default function App() {
 const [selected, setSelected] = useState(false);

 return (
  <div className="App">
    <h1>Testing Style Update</h1>
    <Button
      className={`buttonBase ${selected && "buttonSelected"}`}
      clicked={() => setSelected(!selected)}
      selected={selected}
    />
  </div>
  );
}

按钮

const Button = ({ className, selected, clicked }) => (
  <button className={className} onClick={clicked}>
    {selected
      ? "Click me to Remove the new style"
      : "Click me to add a new style"}
  </button>
);
export default Button;

测试

import React from "react";
import App from "./App";
import Enzyme, { mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import Button from "./Button";

Enzyme.configure({ adapter: new Adapter() });

describe("App", () => {
  it("renders", () => {
    mount(<App />);
});

it("button visually becomes selected when clicked", () => {
const wrapper = mount(<App />);

const btn = wrapper.find(Button);
expect(btn).toBeDefined(); // <- passes
expect(btn.hasClass("buttonSelected")).toEqual(false); // <- passes

btn.simulate("click");
wrapper.update();
expect(btn.hasClass("buttonSelected")).toEqual(true);// <- fails
});

从视觉上看,这按预期工作。

关于在测试中看到状态正确更新,我缺少什么?

我的猜测是,一旦我弄清楚这一点,我就可以将相同的逻辑应用于事物的禁用方面。

提前致谢

这里是沙盒:https://codesandbox.io/s/testingreactusestate-3bvv7

更新: 根据提供的第一个答案,我能够在我的沙箱中通过测试,但在我的开发环境中却没有。

Material-UI 可能会导致一些差异,但我知道我正在寻找的类名:

这里是开发测试

it("Updates it's classes when selected", () => {
  wrapper = mount(
       <ul>// required because the FilterListItem is an 'li' element
        <FilterListItem/>
      </ul>
  );

  let btn = wrapper.find(Button);
  expect(btn).toBeDefined(); // <- PASS
  // verify that the correct style is not present
  expect(btn.hasClass("makeStyles-selected-5")).toEqual(false);// <- PASS

  btn.simulate("click");

  // re-find the node
  btn = wrapper.find(Button);
  expect(btn).toBeDefined(); // <- PASS
  // check that the correct style has now been added
  expect(btn.hasClass("makeStyles-selected-5")).toEqual(true);//<-FAIL
});

【问题讨论】:

    标签: reactjs jestjs material-ui enzyme


    【解决方案1】:

    您的测试是正确的,您唯一错过的是使用酶 3,您需要在触发事件后重新找到您的组件,因为它的属性不会更新 (reference)。

    作为进一步检查,只需在模拟点击事件之前记录包装器:

    btn.simulate("click");
    console.log(wrapper.find(Button).debug()); // re-find Button 
    console.log(btn.debug()); // your code using btn
    

    输出将是

    <Button className="buttonBase buttonSelected"...
    <Button className="buttonBase false"... 
    

    如您所见,组件在click 之后已正确更新。问题只是重新找到您需要测试的组件。

    奖励:你不需要update()

    【讨论】:

    • 所以在我的试验中,我的原始版本让我期待这个:expect(getComputedStyle(wrapper.find(Button).getDOMNode()).getPropertyValue("background-color")) .toBe("透明");效果很好,并且更符合我试图测试的内容。但是当我做同样的事情来检查背景颜色是否改变时,它仍然失败。那本质上不是重新寻找组件吗?
    • 注意:我做了以下操作:expect(getComputedStyle(wrapper.find(Button).getDOMNode()).getPropertyValue("background-color")).toBe("white");模拟点击后,仅供参考
    • 用新材料更新了我的问题
    • 你会更新沙箱还是展示这个新的“makeStyles-selected-5”类是如何在组件中设置的?也是为了调试,在模拟click事件之后,你有没有试过console.log(wrapper.debug())
    • 更新:我将把它作为可接受的答案,因为我意识到生产代码中的按钮是通过 useEffect 而不是 onclick 获取其状态的,感谢您的帮助!
    猜你喜欢
    • 2020-08-12
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 2021-10-07
    • 2020-11-02
    • 2019-08-06
    • 2021-03-19
    相关资源
    最近更新 更多