javascript - 使用 useReducer/useContext 和 React-Testing-Library 时出现“TypeError: dispatch is not a function”
问题描述
我在测试通过 useReducer 和 React-testing-library 使用调度的组件时遇到问题。
我创建了一个不太复杂的示例来尝试总结正在发生的事情,但仍然存在同样的dispatch is not a function
问题。当我运行测试时,我收到此错误:
11 | data-testid="jared-test-button"
12 | onClick={() => {
> 13 | dispatch({ type: 'SWITCH' })
| ^
14 | }}
15 | >
16 | Click Me
另外,如果我做一个console.log(typeof dispatch)
inside RandomButton
,然后单击输出显示的按钮function
。
这是有问题的测试。
import React from 'react'
import RandomButton from '../RandomButton'
import { render, fireEvent } from '@testing-library/react'
describe('Button Render', () => {
it('click button', () => {
const { getByTestId, queryByText } = render(<RandomButton />)
expect(getByTestId('jared-test-button')).toBeInTheDocument()
fireEvent.click(getByTestId('jared-test-button'))
expect(queryByText('My name is frog')).toBeInTheDocument()
})
})
这是我的相关代码:
随机按钮.js
import React, { useContext } from 'react'
import MyContext from 'contexts/MyContext'
const RandomButton = () => {
const { dispatch } = useContext(MyContext)
return (
<div>
<Button
data-testid="jared-test-button"
onClick={() => {
dispatch({ type: 'SWITCH' })
}}
>
Click Me
</Button>
</div>
)
}
export default RandomButton
MyApp.js
import React, { useReducer } from 'react'
import {myreducer} from './MyFunctions'
import MyContext from 'contexts/MyContext'
import RandomButton from './RandomButton'
const initialState = {
blue: false,
}
const [{ blue },dispatch] = useReducer(myreducer, initialState)
return (
<MyContext.Provider value={{ dispatch }}>
<div>
{blue && <div>My name is frog</div>}
<RandomButton />
</div>
</MyContext.Provider>
)
export default MyApp
MyFunctions.js
export const myreducer = (state, action) => {
switch (action.type) {
case 'SWITCH':
return { ...state, blue: !state.blue }
default:
return state
}
}
MyContext.js
import React from 'react'
const MyContext = React.createContext({})
export default MyContext
我错过了一些愚蠢的东西,但是在阅读了文档并在线查看了其他示例之后,我没有看到解决方案。
解决方案
我没有用 react-testing-library 测试过 redux 钩子,但我知道你必须为渲染函数提供一个包装器,为 Provider 提供调度函数。
这是我用来测试连接到 redux 存储的组件的示例:
testUtils.js
import React from 'react';
import { createStore } from 'redux';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import reducer from '../reducers';
// https://testing-library.com/docs/example-react-redux
export const renderWithRedux = (
ui,
{ initialState, store = createStore(reducer, initialState) } = {},
options,
) => ({
...render(<Provider store={store}>{ui}</Provider>, options),
store,
});
因此,根据您分享的内容,我认为您想要的包装器看起来像这样:
import React from 'react';
import MyContext from 'contexts/MyContext';
// export so you can test that it was called with specific arguments
export dispatchMock = jest.fn();
export ProviderWrapper = ({ children }) => (
// place your mock dispatch function in the provider
<MyContext.Provider value={{ dispatch: dispatchMock }}>
{children}
</MyContext.Provider>
);
在你的测试中:
import React from 'react';
import RandomButton from '../RandomButton';
import { render, fireEvent } from '@testing-library/react';
import { ProviderWrapper, dispatchMock } from './testUtils';
describe('Button Render', () => {
it('click button', () => {
const { getByTestId, queryByText } = render(
<RandomButton />,
{ wrapper: ProviderWrapper }, // Specify your wrapper here
);
expect(getByTestId('jared-test-button')).toBeInTheDocument();
fireEvent.click(getByTestId('jared-test-button'));
// expect(queryByText('My name is frog')).toBeInTheDocument(); // won't work since this text is part of the parent component
// If you wanted to test that the dispatch was called correctly
expect(dispatchMock).toHaveBeenCalledWith({ type: 'SWITCH' });
})
})
就像我说的,我不必专门测试 redux 钩子,但我相信这应该能让你找到一个好地方。
推荐阅读
- c++ - 在 C++ 中读取外来字符
- git - 将 Bitbucket-Branch 同步到 GitHub 存储库
- javascript - Ajax 调用后的 Javascript SideBar 问题
- javascript - 当 Bootstrap 脚本或 jquery 在同一页面上时,Javascript 窗口未打开
- npm - CleanWebPackPlugin 错误:CleanwebpackPlugin 不是构造函数
- android - Uno 平台 - 在您与选取器交互之前,Android NumberPicker 无法正确呈现
- python - PySpark列表中的元素与一个或两个元素的差异
- azure - 无法在 azure 容器注册表上运行 docker 映像的实例
- mysql - MySQL:选择、分组和将行转换为单独的列:)
- java - 如何找到数组中每个元素获得某个随机变量的概率?