如何在React Native中用react-test-renderer和jest测试含嵌套Connected组件的组件
解决React Native测试中Connected组件找不到Store的问题
你遇到的问题本质是嵌套的Connect(SocialServiceProfileImage)组件需要Redux store的上下文,但测试时没有提供这个上下文,导致抛出"Invariant Violation"错误。既然你不想用Enzyme或react-redux-mock-store,可以通过手动创建一个极简的Redux store并使用Provider包裹组件来解决,完全不需要额外第三方库。
具体步骤和修改后的代码
- 首先导入
react-redux的Provider和redux的createStore - 创建一个极简的mock store(用空reducer即可,因为你测试的是点击交互,不需要处理真实Redux逻辑)
- 在渲染
ProfileImageSelect时,用Provider包裹它,传入这个mock store
修改后的测试代码如下:
import React from 'react'; import renderer from 'react-test-renderer'; import sinon from 'sinon'; import { clone } from 'lodash'; import { Provider } from 'react-redux'; // 新增导入 import { createStore } from 'redux'; // 新增导入 import { ProfileImageSelect } from '../../../../components/settings/ProfileImageSelect'; const userInfo = { first_name: 'test_first_name', last_name: 'test_last_name' }; // 创建极简mock store,空reducer返回空状态 const mockStore = createStore(() => ({})); describe('<ProfileImageSelect />', () => { let onClose; let onSelect; let socialLogins; beforeEach(() => { socialLogins = { facebook: { id: '187416164', identifier: 'adams_facebook', full_name: 'Eric Adams', profile_pic: 'profile_pic_facebook.jpeg', expired: false }, twitter: { full_name: 'Eric Adams', id: '187416164', identifier: 'adams_ea', profile_pic: 'https://pbs.twimg.com/profile_images/707586445427380226/5uETA8fs.jpg', expired: false }, linkedin: { full_name: 'Eric Adams', id: '8vN6Da_RJJ', identifier: 'adams.ea@gmail.com', profile_pic: 'https://media.licdn.com/dms/image/C5603AQFfn5Ko5IS1NQ/profile-displayphoto-shrink_100_100/0?e=1549497600&v=beta&t=11m5mirEr_R2gf3OOfh3zHTL3Xe2ImrxcZ7l7ebLDa0', expired: false } }; onClose = sinon.stub(); onSelect = sinon.stub(); }); it('calls onClose on the props on click of cancel link ', () => { const connected = clone(socialLogins, true); const testRenderer = renderer.create( // 用Provider包裹组件,传入mock store <Provider store={mockStore}> <ProfileImageSelect onSelect={onSelect} onClose={onClose} socialLogins={connected} userInfo={userInfo} /> </Provider> ); const root = testRenderer.root; root.findByProps({ className: 'cancel' }).props.onPress(); expect(onClose.called).toEqual(true); }); });
为什么这个方案可行
Provider组件会把传入的store注入到整个组件树的React上下文中,嵌套的Connect组件就能通过上下文找到store,解决了找不到store的错误。- 我们创建的mock store极其简单,只需要满足
Connect组件的基本要求即可,不需要处理任何真实的Redux状态逻辑,完全符合你不想使用第三方mock库的需求。 - 这种方式保留了react-test-renderer的完整渲染能力,让你可以正常查找DOM节点并测试交互行为,不用切换到浅渲染。
内容的提问来源于stack exchange,提问作者kamlesh paliwal
相关产品推荐
相关产品推荐

