繁体   English   中英

Dispatch 不是 function - 带有 React Redux Hooks 的 React 测试库

[英]Dispatch is not a function - React Testing Library with React Redux Hooks

我想测试组件是否正在向商店发送动作,为此,我必须模拟 React Hooks 的功能。

我正在使用 useDispatch 挂钩来获取调度程序 function 并将其放入变量中,以便我可以调用它。

当我运行我的测试套装时,即使 useDispatch function 被模拟,它也会返回一个错误,指出它不是 function。

jest.mock('react-redux', () => ({
  useSelector: jest.fn(),
  useDispatch: jest.fn(() => {}),
}));

it('should be able open modal', () => {
  const { getByTestId } = render(<Dropdown />);

  fireEvent.click(getByTestId('dropdown'));
  fireEvent.click(getByTestId('button-Transactions'));

  const dispatch = jest.fn();
  useDispatch.mockReturnValue(dispatch);

  expect(dispatch).toHaveBeenCalledWith(openModal('transactions'));
});

错误:

    TypeError: dispatch is not a function

      19 | 
      20 |     if (item.action) {
    > 21 |       dispatch(item.action);
         |       ^
      22 |     }
      23 | 
      24 |     return item;

我的组件:

const history = useHistory();
  const dispatch = useDispatch();

  function handleNavigation(item) {
    if (item.path) return history.push(item.path);

    if (item.action) {
      dispatch(item.action);
    }

    return item;
  }

该组件试图执行尚未声明的 function。 我们需要在渲染方法之前模拟

const dispatch = jest.fn();
useDispatch.mockReturnValue(jest.fn());

const dropdown = render(<Dropdown />);

这是因为当你模拟它时,你没有指定一个值。

我想到了两种方法来做到这一点:

  1. 在您的测试中有一个真实的商店,因此您可以测试集成:
const mockedStore = { /* the things you need in store in your test */ };
const store = configureStore(mockedStore, browserHistory);

const { getByTestId } = render(<Provider store={store}><Dropdown /></Provider>);
  1. 模拟你的dispatch ,但你最终会遇到无限的useSelector问题(特别是如果你在渲染的树中有多个 useSelector )。
import * as ReactRedux from 'react-redux';

// useDispatch returns a function which we are mocking here
const mockDispatch = jest.fn();

beforeAll(() => {
  ReactRedux.useDispatch = jest.fn().mockImplementation(() => mockDispatch);
});

beforeEach(() => {
  ReactRedux.useDispatch.mockClear();
});


expect(mockDispatch).toHaveBeenCalledWith(yourAction);

请注意,您将面临的真正问题不是调度,而是useSelector 如果你模拟它,它会返回你想要的值。 但是,如果你的树中有不止一个呢? 为此,据我所知,我需要真正的商店。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM