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

How to test function in private scope?

当我尝试直接测试它时,我无法断言函数 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

正如上面评论中所讨论的那样,测试某些内部结构是不好的举动。想象一下这是可能的,我们重命名了该内部函数或将其内联或拆分为两个。我们测试它的测试会失败吗?确实。我们的应用程序会崩溃吗?当然不是。

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

  1. imports(如输入值)
  2. props(也是输入值)
  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);
});