javascript - 为什么这些 Jest 测试失败了?类型错误 : Cannot read property 'apply' of undefined

标签 javascript reactjs react-redux jestjs enzyme

我有 2 个组件/测试 Login.js 和 Routes.js 都有相同的错误:

TypeError: Cannot read property 'apply' of undefined enter image description here

不确定这里要应用什么......


组件

登录.js

import React from 'react'
import { connect } from "react-redux"
import { bindActionCreators } from 'redux'; 
import { setCurrentUser } from '../../actions/authActions'
import * as api from '../../services/api'
import Notification from '../common/Notification'

const mapDispatchToProps = (dispatch) => {
    return {
        setUser: (user) => {
            bindActionCreators(setCurrentUser(user), dispatch)
        }
    }
};

export class LoginContainer extends React.Component {
    constructor(props) {
        super(props)

        this.state = {};

        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleSubmit(e) {
        ...
    }

    render() {
        return (
            <div className="app-bg">
                ...
            </div>
        )
    }
}

export default connect(null, mapDispatchToProps)(LoginContainer); 

路由.js

import React from 'react'
import { Route, Switch } from 'react-router-dom'
import LoginContainer from './auth/Login'
import Dashboard from './Dashboard'
import NoMatch from './NoMatch'

const Routes = () => {
    return (
        <Switch>
            <Route exact={ true } path="/" component={ LoginContainer }/>
            <Route path="/dashboard" component={ Dashboard }/>
            <Route component={ NoMatch } />
        </Switch>
    );
}

export default Routes

测试

登录.test

import React from 'react'
import { Provider } from "react-redux"
import ReactTestUtils from 'react-dom/test-utils'
import { createCommonStore } from "../../store";
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
// import Login from './Login'
import { LoginContainer as Login } from './Login';
import Notification from '../common/Notification'

const store = createCommonStore();

const user = {
    id: 1,
    role: 'Admin',
    username: 'leongaban'
};
const loginComponent = shallow(
    <Provider store={store}>
        <LoginContainer/>
    </Provider>
);
const fakeEvent = { preventDefault: () => '' };

describe('<Login /> component', () => {
    it('should render', () => {
        const tree = toJson(loginComponent);
        expect(tree).toMatchSnapshot();
    });

    it('should contains the words "Forgot Password"', () => {
        expect(loginComponent.contains('Forgot Password')).toBe(true);
    });

    it('should render the Notification component if state.error is true', () => {
        loginComponent.setState({ error: true });
        expect(loginComponent.find(Notification).length).toBe(1);
    });
});

路由测试

import React from 'react'
import { Provider } from "react-redux"
import { mount, shallow } from 'enzyme'
import { MemoryRouter } from 'react-router'
import { createCommonStore } from "../store";
import toJson from 'enzyme-to-json'

import Routes from './Routes'
import Login from './auth/Login'
import Dashboard from './Dashboard'
import NoMatch from './NoMatch'

const store = createCommonStore();

const routesMount = (path) => {
    return mount(
        <Provider store={store}>
            <MemoryRouter initialEntries={[ path ]} initialIndex={0}>
                <Routes />
            </MemoryRouter>
        </Provider>
    );
};

describe('<Routes /> component', () => {
    it('should save a snapshot', () => {
        const routesComponent = shallow(<Routes />);
        const tree = toJson(routesComponent);
        expect(tree).toMatchSnapshot();
    });

    it('should render Login component when visiting /', () => {
        const routesComponent = routesMount('/');
        expect(routesComponent.find(Login).length).toBe(1);
    });

    it('should render Dashboard component when visiting /dashboard', () => {
        const routesComponent = routesMount('/dashboard');
        expect(routesComponent.find(Dashboard).length).toBe(1);
    });

    it('should render the NoMatch component when visiting invalid path', () => {
        const routesComponent = routesMount('/404');
        expect(routesComponent.find(NoMatch).length).toBe(1);
    });
});

商店

商店.js

The Redux Chrome plugin 窗口.__REDUX_DEVTOOLS_EXTENSION__ && 窗口.__REDUX_DEVTOOLS_EXTENSION__()

import React from "react"
import { applyMiddleware, combineReducers, compose, createStore} from "redux"
import thunk from "redux-thunk"
import { userReducer } from "./reducers/UserReducer"
import { authReducer } from "./reducers/AuthReducer"

export const createCommonStore = (trackStore=false) => {
    const reducers = combineReducers({
        user: userReducer,
        user: authReducer
    });

    //noinspection JSUnresolvedVariable
    const store = createStore(reducers,
        compose(
            applyMiddleware(thunk),
            window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
        )
    );

    if (trackStore) {
        store.subscribe((() => {
            console.log("  store changed", store.getState());
        }));
    }

    return store;
};

最佳答案

store.js 中,表达式 window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 的计算结果为 undefined。这会导致 compose 中的错误。插件文档有 solution为此:

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducers,
    composeEnhancers(
        applyMiddleware(thunk),
    )
);

关于javascript - 为什么这些 Jest 测试失败了?类型错误 : Cannot read property 'apply' of undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44523873/

相关文章:

javascript - 我正在尝试在 codepen 中构建一个 React-Redux 'Markdown Previewer',但是我在弄清楚应该做什么时遇到了很多麻烦

Javascript Tab 键按下并按住 Tab 时,它会无限闪烁

javascript - 将 info.selectionText 的值传递给内容脚本

javascript - 如何以编程方式更改 html select 标记中的选定选项

javascript - 无法在编辑器中显示图像

javascript - 如何获取日期数组之间的 StartDate 和 EndData

redux - 不可变 JS - 合并从数组创建 map 对象列表

javascript - 无法使用 mvc4 将数据附加到 jquery 中的表

css - 如何覆盖 material-ui react 组件的 @media css

javascript - 我可以在 Javascript 中再次导入吗?