最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dispatch is not a function - React Testing Library with React Redux Hooks - Stack Overflow

programmeradmin2浏览0评论

I want to test if the ponent is dispatching an action to the store, for this, i have to mock the functionalities of React Hooks.

I'm using the useDispatch hook to get the dispatcher function and put inside a variable so them i can call it.

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

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

I want to test if the ponent is dispatching an action to the store, for this, i have to mock the functionalities of React Hooks.

I'm using the useDispatch hook to get the dispatcher function and put inside a variable so them i can call it.

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

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;
  }
Share Improve this question edited Apr 9, 2020 at 16:56 Laura Beatris asked Apr 9, 2020 at 16:24 Laura BeatrisLaura Beatris 1,9329 gold badges31 silver badges57 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

The ponent was trying to execute a function that wasn't declared yet. 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).
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. 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.

发布评论

评论列表(0)

  1. 暂无评论