You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Enzyme测试Redux连接组件时遇store找不到的问题

解决Enzyme测试Redux连接组件时的Could not find "store" in either the context or props错误

你遇到的这个错误我之前也碰到过,本质是Redux的connect高阶组件找不到它需要的store实例——毕竟测试环境里不像正式项目那样有Provider把store注入到组件树的context里。先回顾下你的测试代码和引入的脚本:

你的测试代码:

import React from 'react'
import { shallow, mount, render } from 'enzyme'
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
import Login from '../../src/routes/login/components/Login'

configure({ adapter: new Adapter() })

describe('<Login />', () => {
  test('component has form-group nodes', () => {
    const component = shallow(<Login />).dive()
    expect(component.find('.form-group')).to.have.length(2)
  });
});

引入的外部脚本:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

下面给你几种实用的解决办法,你可以根据测试场景选择:

方法1:直接测试未连接的原始组件(最推荐)

一般来说,我们测试组件的UI逻辑时,不需要重复测试Redux的连接逻辑(这部分Redux官方已经验证过了),所以直接测试未被connect包裹的纯React组件是最省心的。

在你的Login组件文件里,除了默认导出连接后的组件,额外导出原始的未连接组件:

// Login.jsx
import { connect } from 'react-redux';

// 导出原始纯组件
export const Login = (props) => {
  // 组件的UI和业务逻辑
};

// 连接后的组件作为默认导出
export default connect(mapStateToProps, mapDispatchToProps)(Login);

然后在测试文件里导入这个命名导出的原始组件:

// 修改导入语句
import { Login } from '../../src/routes/login/components/Login'

// 测试代码简化,不需要dive
describe('<Login />', () => {
  test('component has form-group nodes', () => {
    const component = shallow(<Login />)
    expect(component.find('.form-group')).to.have.length(2)
  });
});

这样就完全不需要处理store的问题,专注测试组件本身的UI表现即可。

方法2:给连接后的组件传递store props

如果你一定要测试连接后的组件,可以创建一个mock store,然后把它作为props直接传给组件:

首先安装redux-mock-store(开发依赖):

npm install redux-mock-store --save-dev

然后修改测试代码:

import React from 'react'
import { shallow } from 'enzyme'
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
import configureMockStore from 'redux-mock-store';
import Login from '../../src/routes/login/components/Login'

configure({ adapter: new Adapter() })
const mockStore = configureMockStore();
// 可以传入mock的state数据,模拟不同状态下的组件表现
const store = mockStore({ auth: { isLoading: false } });

describe('<Login />', () => {
  test('component has form-group nodes', () => {
    const component = shallow(<Login store={store} />).dive()
    expect(component.find('.form-group')).to.have.length(2)
  });
});

方法3:通过Enzyme的context传递store

另一种方式是利用Enzyme shallow渲染的context选项来传递store:

import React from 'react'
import { shallow } from 'enzyme'
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
import configureMockStore from 'redux-mock-store';
import Login from '../../src/routes/login/components/Login'

configure({ adapter: new Adapter() })
const mockStore = configureMockStore();
const store = mockStore({});

describe('<Login />', () => {
  test('component has form-group nodes', () => {
    const component = shallow(<Login />, { context: { store } }).dive()
    expect(component.find('.form-group')).to.have.length(2)
  });
});

方法4:用Provider包裹组件(适合mount完整渲染)

如果你需要用mount进行完整渲染(比如测试组件生命周期、子组件交互),可以用Redux的Provider组件把Login包裹起来,注入store:

import React from 'react'
import { mount } from 'enzyme'
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import Login from '../../src/routes/login/components/Login'

configure({ adapter: new Adapter() })
const mockStore = configureMockStore();
const store = mockStore({});

describe('<Login />', () => {
  test('component has form-group nodes', () => {
    const component = mount(
      <Provider store={store}>
        <Login />
      </Provider>
    );
    expect(component.find('.form-group')).to.have.length(2)
  });
});

内容的提问来源于stack exchange,提问作者Dmytro P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:49:43