Dispatch 不是一个函数 - 带有 React Redux Hooks 的 React 测试库
Dispatch is not a function - React Testing Library with React Redux Hooks
我想测试组件是否正在向商店发送操作,为此,我必须模拟 React Hooks 的功能。
我正在使用 useDispatch 挂钩获取调度程序函数并将其放入一个变量中以便我可以调用它。
当我 运行 我的测试服时,即使 useDispatch 函数被模拟,它 returns 一个错误说它不是一个函数。
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;
}
因为你mock的时候没有指定值
我想到了两种方法:
- 在你的测试中有一个真实的商店,所以你可以测试集成:
const mockedStore = { /* the things you need in store in your test */ };
const store = configureStore(mockedStore, browserHistory);
const { getByTestId } = render(<Provider store={store}><Dropdown /></Provider>);
- 模拟你的
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
。
如果你模拟它,它会 return 你想要的值。但是如果你的树中不止一个呢?为此,据我所知,我需要真正的商店。
该组件试图执行一个尚未声明的函数。
我们需要在渲染方法之前模拟
const dispatch = jest.fn();
useDispatch.mockReturnValue(jest.fn());
const dropdown = render(<Dropdown />);
我想测试组件是否正在向商店发送操作,为此,我必须模拟 React Hooks 的功能。
我正在使用 useDispatch 挂钩获取调度程序函数并将其放入一个变量中以便我可以调用它。
当我 运行 我的测试服时,即使 useDispatch 函数被模拟,它 returns 一个错误说它不是一个函数。
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;
}
因为你mock的时候没有指定值
我想到了两种方法:
- 在你的测试中有一个真实的商店,所以你可以测试集成:
const mockedStore = { /* the things you need in store in your test */ };
const store = configureStore(mockedStore, browserHistory);
const { getByTestId } = render(<Provider store={store}><Dropdown /></Provider>);
- 模拟你的
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
。
如果你模拟它,它会 return 你想要的值。但是如果你的树中不止一个呢?为此,据我所知,我需要真正的商店。
该组件试图执行一个尚未声明的函数。 我们需要在渲染方法之前模拟
const dispatch = jest.fn();
useDispatch.mockReturnValue(jest.fn());
const dropdown = render(<Dropdown />);