如何使用 React-Testing-Library 测试 mapDispatchToProps?
Posted
技术标签:
【中文标题】如何使用 React-Testing-Library 测试 mapDispatchToProps?【英文标题】:How can I test the mapDispatchToProps with React-Testing-Library? 【发布时间】:2021-11-30 03:21:45 【问题描述】:我必须测试以下组件:
import React from 'react';
import connect from 'react-redux';
import open as openModal from 'redux/actions/ModalActions';
import MODAL_CONTENT_ADD_TO_ALBUM from 'constants/ModalNameConstants';
import ContentAddToAlbumModal from 'components/ContentAddToAlbumModal';
import AddSection from 'components/AddSection';
export function AddToAlbumButton(props)
const openUploadModal = props;
return (
<>
<div>
<div>
<AddSection
onClick=openUploadModal
/>
</div>
</div>
<ContentAddToAlbumModal/>
</>
);
function mapDispatchToProps(dispatch, props)
return
openUploadModal()
return dispatch(
openModal(MODAL_CONTENT_ADD_TO_ALBUM, props.content.get('id'))
);
,
;
export default connect(null, mapDispatchToProps)(AddToAlbumButton);
我的测试用例如下:
import React from 'react';
import render from '@testing-library/react';
import AddToAlbumButton from 'components/AddToAlbumButton';
jest.mock('components/ContentAddToAlbumModal', () =>
return function ContentAddToAlbumModal()
return (
<div>
ContentAddToAlbumModal
</div>
)
;
);
jest.mock('components/AddSection', () =>
return function AddSection(openUploadModal)
return (
<div onClick=openUploadModal>
AddSection
</div>
)
;
);
describe('AddToAlbumButton component', () =>
const props =
openUploadModal: jest.fn()
;
it('Should render snapshot of AddToAlbumButton component correctly', () =>
const asFragment = render(<AddToAlbumButton ...props />);
expect(asFragment()).toMatchSnapshot();
)
);
我也想测试我的 mapDispatchToProps 函数,如何在不公开导出的情况下测试它。我应该如何测试连接的组件?
我在网上寻找建议。我发现的一个方法是通过在 jest 目录的 mocks 文件夹中创建一个文件来模拟“react-redux”模块,代码 sn-p 为:
const mockDispatch = jest.fn(action => action);
module.exports =
connect: (mapStateToProps, mapDispatchToProps) => reactComponent => (
mapStateToProps,
mapDispatchToProps: (dispatch = mockDispatch, ownProps) => (
mapDispatchToProps(dispatch, ownProps)
),
[reactComponent.displayName || reactComponent.name || 'reactComponent']: reactComponent,
mockDispatch,
),
Provider: ( children ) => children,
;
我应该如何将上面的代码 sn-p 与“React 测试库”一起使用。我的测试用例缺少什么?我应该怎么做?
谢谢
【问题讨论】:
【参考方案1】:您可以使用redux-mock-store 包创建模拟商店。用这个模拟商店用Provider
包装你的组件。
您可以通过调用store.getActions()
获取所有操作。最后,您可以使用任何断言库来测试有效负载。
这种测试方式更接近于集成测试,集成了React组件、connect
、mapDispatchToProps
函数。
index.tsx
:
import React from 'react';
import connect from 'react-redux';
import open as openModal from './actions';
import ContentAddToAlbumModal from './components/ContentAddToAlbumModal';
import AddSection from './components/AddSection';
const MODAL_CONTENT_ADD_TO_ALBUM = 'MODAL_CONTENT_ADD_TO_ALBUM';
export function AddToAlbumButton(props)
return (
<>
<AddSection onClick=props.openUploadModal />
<ContentAddToAlbumModal />
</>
);
function mapDispatchToProps(dispatch, props)
return
openUploadModal()
return dispatch(openModal(MODAL_CONTENT_ADD_TO_ALBUM, props.content.get('id')));
,
;
export default connect(null, mapDispatchToProps)(AddToAlbumButton);
components/ContentAddToAlbumModal.tsx
:
import React from 'react';
export default function ContentAddToAlbumModal()
return <div>real ContentAddToAlbumModal</div>;
components/AddSection.tsx
:
import React from 'react';
export default function AddSection( onClick )
return <div onClick=onClick>real AddSection</div>;
actions.ts
:
export function open(type, id)
return type, payload: id ;
index.test.tsx
:
import render, fireEvent, screen from '@testing-library/react';
import React from 'react';
import Provider from 'react-redux';
import createMockStore from 'redux-mock-store';
import AddToAlbumButton from './';
const mockStore = createMockStore();
jest.mock('./components/ContentAddToAlbumModal', () =>
return function ContentAddToAlbumModal()
return <div>ContentAddToAlbumModal</div>;
;
);
jest.mock('./components/AddSection', () =>
return function AddSection( onClick )
return <div onClick=onClick>AddSection</div>;
;
);
describe('AddToAlbumButton', () =>
test('should pass', () =>
const store = mockStore();
const content =
get(key)
return '123';
,
;
render(
<Provider store=store>
<AddToAlbumButton content=content />
</Provider>
);
fireEvent.click(screen.getByText(/AddSection/));
expect(store.getActions()).toEqual([ type: 'MODAL_CONTENT_ADD_TO_ALBUM', payload: id: '123' ]);
);
);
测试结果:
PASS examples/69525117/index.test.tsx (8.636 s)
AddToAlbumButton
✓ should pass (35 ms)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
actions.ts | 100 | 100 | 100 | 100 |
index.tsx | 100 | 100 | 100 | 100 |
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 9.788 s, estimated 10 s
【讨论】:
以上是关于如何使用 React-Testing-Library 测试 mapDispatchToProps?的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]
如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?