【问题标题】:how to check counter value is incremented or not in react?如何检查计数器值是否增加或没有反应?
【发布时间】:2020-11-14 22:51:57
【问题描述】:

我做了一个简单的计数器演示,我有两个按钮 incrementdecrement.demo 工作正常。但现在我想测试我的组件。当我点击increment button 时,我的测试用例失败。我正在使用enzymejest

这是我的代码 https://codesandbox.io/s/quirky-tharp-ty92o?file=/src/App.test.js

测试用例失败

test("clicking button increments counter display", () => {
  const counter = 7;
  const wrapper = setup(null, { counter });

  // find button and click
  const button = findByTestAttr(wrapper, "increment-button");
  button.simulate("click");

  // find display and test value
  const counterDisplay = findByTestAttr(wrapper, "counter-display");
  expect(counterDisplay.text()).toContain(counter + 1);
});

遇到错误

ShallowWrapper::setState() 只能在类组件上调用

【问题讨论】:

  • if (state) wrapper.setState(state) 这是在做什么?
  • 我想我正在使用function component。它是class component的方法
  • 也许你正在尝试测试错误的东西。

标签: javascript reactjs jestjs react-hooks enzyme


【解决方案1】:

您无法操纵功能组件的内部状态,尤其是基于类的this.setState

0 是计数器的初始默认状态,因此您只需测试单击“+”按钮将 UI 更新为 1

const setup = (props = {}, state = null) => {
  const wrapper = shallow(<App {...props} />);
  // if (state) wrapper.setState(state); // <-- can't do this!!
  return wrapper;
};

...

test("clicking button increments counter display", () => {
  const wrapper = setup(); // initial count is 0

  // find button and click
  const button = findByTestAttr(wrapper, "increment-button");
  button.simulate("click");

  // find display and test value
  const counterDisplay = findByTestAttr(wrapper, "counter-display");
  expect(counterDisplay.text()).toContain(1); // new count is 1
});

更新以提供初始道具

暴露一些初始值 prop 传递给钩子

export default function App({ initialCount }) {
  const { state, increment, decrement } = useCounter(initialCount);
  return (
    <div className="App" data-test="component-app">
      <h1 data-test="counter-display">{state}</h1>
      <button data-test="increment-button" onClick={increment}>
        +
      </button>
      <button data-test="decrement-button" onClick={decrement}>
        -
      </button>
    </div>
  );
}

更新钩子以将初始值传递给状态(正确使用功能状态更新!!

export default (initialCount) => {
  const [state, setState] = React.useState(initialCount);

  const increment = () => {
    setState(preState => preState + 1);
  };

  const decrement = () => {
    setState(preState => preState - 1);
  };

  return {
    state,
    increment,
    decrement
  };
};

并更新测试套件

const setup = (props = {}) => {
  const wrapper = shallow(<App {...props} />);
  return wrapper;
};

...

test("clicking button increments counter display", () => {
  const initialCount = 10;
  const wrapper = setup({ initialCount });

  // find button and click
  const button = findByTestAttr(wrapper, "increment-button");
  button.simulate("click");

  // find display and test value
  const counterDisplay = findByTestAttr(wrapper, "counter-display");
  expect(counterDisplay.text()).toContain(initialCount + 1);
});

建议:考虑切换到 React 测试库,它实际上更直观,并以用户与其交互的方式测试组件,而不是干预内部实现细节,本质上更像是您上次测试的工作方式。

【讨论】:

  • 我对@9​​87654331@ 的改动很小,给出了一些初始值(从它开始递增)和递减
  • @user944513 你需要暴露App中的prop,比如function App({ initialCount}) {...,然后把它传递给useCounter,比如const {...} = useCounter(initialCount);。如果这是您真正想要的,我可以更新我的答案和沙盒。
  • 我们可以模拟useCounter 吗?
  • 感谢suggestion。我们可以在同一个项目中同时使用React Testing Library 和酶吗?
猜你喜欢
  • 2011-11-08
  • 2017-02-26
  • 2021-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多