使用酶和反应钩子修改计数器无效

时间:2020-07-17 01:41:52

标签: reactjs jestjs enzyme

晕,我现在正在学习用玩笑,酵素和钩子进行反应测试。当同时使用减量和增量时,我发现了一个问题。递减无效。

App.js

import React, { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);
  const [err, setErr] = useState(false);

  const decrement = () => {
    if (count < 1) {
      setErr(true);
    } else {
      setCount((x) => (x -= 1));
    }
  };

  const increment = () => {
    setCount((x) => (x += 1));
  };

  return (
    <div data-test="component-app" className="App">
      <h1 data-test="counter-display">{count}</h1>
      {err && (
        <h1 data-test="error-message" color="red">
          Cant increment below zero
        </h1>
      )}
      <button data-test="increment-button" onClick={increment}>
        Add
      </button>
      <button data-test="decrement-button" onClick={decrement}>
        Dec
      </button>
    </div>
  );
}

export default App;

App.test.js

test('should decrement value display', () => {
    const plusButton = wrapper.find('[data-test="increment-button"]');
    const minButton = wrapper.find('[data-test="decrement-button"]');

    plusButton.props().onClick();
    plusButton.props().onClick();
    minButton.props().onClick();
    const counterDisplay = wrapper.find('[data-test="counter-display"]');

    expect(counterDisplay.text()).toBe('1'); // failed -> it always received 2 instead 1.
  });

我该如何解决?

1 个答案:

答案 0 :(得分:1)

要通过测试,请使用mount而不是shallow;

const wrapper = mount(<App/>)

并使用simulate('click')代替props().onClick();

  plusButton.simulate('click');
  plusButton.simulate('click');
  minButton.simulate('click');

这是一种模拟渲染的dom迭代的方法。

您的测试实际上失败了,因为在浅层时,组件并未真正呈现为安装。 minButton的初始App组件状态参考(为0),但在其他按钮单击时未获得其更新的状态参考。由于minButton具有限制if (count < 1),因此更新状态不会触发。

要使测试按预期的那样浅,您需要在包装器的状态已更新后从包装器创建minButton:

  const wrapper = shallow(<App />);
  const plusButton = wrapper.find('[data-test="increment-button"]');
  
  plusButton.props().onClick()
  plusButton.props().onClick()
  // wrapper state is now 2, hence minButton will be able to update state properly
  const minButton = wrapper.find('[data-test="decrement-button"]');
  minButton.props().onClick()
  const counterDisplay = wrapper.find('[data-test="counter-display"]');

  expect(counterDisplay.text()).toBe("1"); // now works, weee :)