简体   繁体   English

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

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

I want to test if the component is dispatching an action to the store, for this, i have to mock the functionalities of React Hooks.我想测试组件是否正在向商店发送动作,为此,我必须模拟 React Hooks 的功能。

I'm using the useDispatch hook to get the dispatcher function and put inside a variable so them i can call it.我正在使用 useDispatch 挂钩来获取调度程序 function 并将其放入变量中,以便我可以调用它。

When i run my test suits, even if the useDispatch function is mocked, it returns an error saying that it's not a 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'));
});

The error:错误:

    TypeError: dispatch is not a function

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

My component:我的组件:

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;
  }

The component was trying to execute a function that wasn't declared yet.该组件试图执行尚未声明的 function。 We need to mock before of the render method我们需要在渲染方法之前模拟

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

const dropdown = render(<Dropdown />);

It is because when you mocked it, you haven't specified a value.这是因为当你模拟它时,你没有指定一个值。

I thought of two ways to do this:我想到了两种方法来做到这一点:

  1. Having a real store in your test, so you can test the integration:在您的测试中有一个真实的商店,因此您可以测试集成:
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. Mock your dispatch , but you ll end up having infinite issues with useSelector (especially if you have more than one useSelector in the tree you rendered).模拟你的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);

Please note that the real issue you will face is not with dispatch, but with useSelector .请注意,您将面临的真正问题不是调度,而是useSelector If you mock it, it will return the value you want.如果你模拟它,它会返回你想要的值。 But what if you have more than one in your tree?但是,如果你的树中有不止一个呢? for that, I real store is necessary as far as I know.为此,据我所知,我需要真正的商店。

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

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