如何在私有范围内测试功能?

时间:2020-08-14 19:28:04

标签: reactjs typescript jestjs react-testing-library

当我尝试直接测试功能selectXHandler时,我无法声明该功能。由于它是在私有范围内定义的。我无法模拟或监视此功能,因为您无法访问

export const CheckboxWrapper = ({
  x,
  y,
  z,
  a = [],
}: CheckboxWrapperProps) => {
  const State = useContext(Context);
  const [state, dispatch] = State;
  const { Items } = state;

  const selectXHandler = () => {
    const payload = {
      x,
      a,
    };
    dispatch({ type: action, payload });
  };

  if (y) {
    return (
      <div className="mt5">
        <Checkbox
          checked={selectedItems[x] !== undefined}
          label={z}
          onChange={selectXHandler}
        />
      </div>
    );
  }
  return null;
};
    const selectXHandler = jest.fn();
    await fireEvent.click(checkbox);
    expect(checkbox).toBeChecked();

    expect(selectXHandler).toHaveBeenCalledTimes(1);

我遇到以下错误:

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

1 个答案:

答案 0 :(得分:1)

正如上面评论中所讨论的,测试某些内部组件是不好的举动。想象一下有可能,我们重命名了该内部函数或对其进行内联或拆分为两个。我们的测试会失败吗?绝对是我们的应用程序会坏吗?当然不是。

我们应该绑定到公共接口。对于组件的公共接口是:

  1. import s(例如输入值)
  2. 道具(也是输入值)
  3. 渲染结果(输出值)
  4. 使用上下文(也可以当作输入值)

所以我以另一种方式看到测试:

  1. 一些输入道具
  2. 我们模拟点击复选框
  3. 并验证是否已使用某些所需的参数调用了上下文中的dispatch

我对RTL的了解不多,因此我的样本将涉及酶。但是我敢肯定,将其转换为适当的RTL选择器查询会很容易。

import Context from '../where/its/placed/someContext.js'; 


it('dispatch is called with A on checkbox is clicked', () => {
  const dispatch = jest.fn();
  const state = {}; // or some initial state your test requires

  const ourComponent = mount(<Content.Provider value={{ dispatch, state }}>
    <CheckboxWrapper {...somePropsYouNeed} /></Content.Provider>);
  ourComponent.find({label: 'some-label'}).simulate('change');

  expect(dispatch).toHaveBeenCalledWith({ type: 'someType', payload: 'somePayload' });
  expect(dispatch).toHaveBeenCalledTimes(1);
});