嗨,我正在使用笑话和酶编写功能组件的测试。当我模拟单击时,组件的params(使用useState的组件状态)会发生变化。当状态更改后,useEffect调用,在useEffect中,我将在更改后分派一些带有参数的异步动作。所以我想用派遣动作来测试参数。为此,我想模拟调度。我该如何实现?任何人都可以帮助我,在此先感谢。下面,我分享代码。
component.js
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useSelector, useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { clientOperations, clientSelectors } from '../../store/clients';
import Breadcrumb from '../../components/UI/Breadcrumb/Breadcrumb.component';
import DataTable from '../../components/UI/DataTable/DataTable.component';
import Toolbar from './Toolbar/Toolbar.component';
const initialState = {
search: '',
type: '',
pageNo: 0,
rowsPerPage: 10,
order: 'desc',
orderBy: '',
paginated: true,
};
const Clients = ({ history }) => {
const { t } = useTranslation();
const dispatch = useDispatch();
const totalElements = useSelector(state => state.clients.list.totalElements);
const records = useSelector(clientSelectors.getCompaniesData);
const [params, setParams] = useState(initialState);
useEffect(() => {
dispatch(clientOperations.fetchList(params));
}, [dispatch, params]);
function updateParams(newParams) {
setParams(state => ({
...state,
...newParams,
}));
}
function searchHandler(value) {
updateParams({
search: value,
pageNo: 0,
});
}
function typeHandler(event) {
updateParams({
type: event.target.value,
pageNo: 0,
});
}
function reloadData() {
setParams(initialState);
}
const columns = {
id: t('CLIENTS_HEADING_ID'),
name: t('CLIENTS_HEADING_NAME'),
abbrev: t('CLIENTS_HEADING_ABBREV'),
};
return (
<>
<Breadcrumb items={[{ title: 'BREADCRUMB_CLIENTS' }]}>
<Toolbar
search={params.search}
setSearch={searchHandler}
type={params.type}
setType={typeHandler}
reloadData={reloadData}
/>
</Breadcrumb>
<DataTable
rows={records}
columns={columns}
showActionBtns={true}
deletable={false}
editHandler={id => history.push(`/clients/${id}`)}
totalElements={totalElements}
params={params}
setParams={setParams}
/>
</>
);
};
Component.test.js
const initialState = {
clients: {
list: {
records: companies,
totalElements: 5,
},
},
fields: {
companyTypes: ['All Companies', 'Active Companies', 'Disabled Companies'],
},
};
const middlewares = [thunk];
const mockStoreConfigure = configureMockStore(middlewares);
const store = mockStoreConfigure({ ...initialState });
const originalDispatch = store.dispatch;
store.dispatch = jest.fn(originalDispatch)
// configuring the enzyme we can also configure using Enjym.configure
configure({ adapter: new Adapter() });
describe('Clients ', () => {
let wrapper;
const columns = {
id: i18n.t('CLIENTS_HEADING_ID'),
name: i18n.t('CLIENTS_HEADING_NAME'),
abbrev: i18n.t('CLIENTS_HEADING_ABBREV'),
};
beforeEach(() => {
const historyMock = { push: jest.fn() };
wrapper = mount(
<Provider store={store}>
<Router>
<Clients history={historyMock} />
</Router>
</Provider>
);
});
it('on changing the setSearch of toolbar should call the searchHandler', () => {
const toolbarNode = wrapper.find('Toolbar');
expect(toolbarNode.prop('search')).toEqual('')
act(() => {
toolbarNode.props().setSearch('Hello test');
});
toolbarNode.simulate('change');
****here I want to test dispatch function in useEffect calls with correct params"**
wrapper.update();
const toolbarNodeUpdated = wrapper.find('Toolbar');
expect(toolbarNodeUpdated.prop('search')).toEqual('Hello test')
})
});
如果您模拟,react-redux
您将能够验证useDispatch
调用参数。同样在这种情况下,您将需要重新创建useSelector
的逻辑(这非常简单,实际上您不必使模拟成为一个钩子)。同样,使用这种方法,您甚至不需要模拟存储<Provider>
。
import { useSelector, useDispatch } from 'react-redux';
const mockDispatch = jest.fn();
jest.mock('react-redux', () => ({
useSelector: jest.fn(),
useDispatch: () => mockDispatch
}));
it('loads data on init', () => {
const mockedDispatch = jest.fn();
useSelector.mockImplementation((selectorFn) => selectorFn(yourMockedStoreData));
useDispatch.mockReturnValue(mockedDispatch);
mount(<Router><Clients history={historyMock} /></Router>);
expect(mockDispatch).toHaveBeenCalledWith(/*arguments your expect*/);
});
我已经尝试过您的建议,但是无法使用此方法安装组件。给出错误TypeError:_reactRedux.useSelector.mockImplementation不是函数
您是否都将
jest.mock(...
和都import ... from 'react-redux'
放入了测试文件中?是的,我把两者都放了。
添加了关于对模拟使用分解回调的描述
jest.mock('react-redux'); useDispatch.mockImplementation(() => store.dispatch) useSelector.mockImplementation(() => { }); it('loads data on init', () => { const historyMock = { push: jest.fn() }; let wrapper; wrapper = mount(<Router><Clients history={historyMock} /></Router>); expect(wrapper).toMatchSnapshot(); });
通过使用此react-redux是模拟的,但如何从useSelector提供数据?如果我不通过使用这种方法来模拟useDispatch.mockImplementation(()=> store.dispatch),则它的诸如dispatch之类的给出错误不是函数。