为啥这些 Jest 测试失败了? TypeError:无法读取未定义的属性“应用”

Posted

技术标签:

【中文标题】为啥这些 Jest 测试失败了? TypeError:无法读取未定义的属性“应用”【英文标题】:Why are these Jest tests failing? TypeError: Cannot read property 'apply' of undefined为什么这些 Jest 测试失败了? TypeError:无法读取未定义的属性“应用” 【发布时间】:2017-11-15 08:56:00 【问题描述】:

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

TypeError:无法读取未定义的属性“应用”

不确定要在此处应用什么...


组件

登录.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); 

Routes.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

测试

登录测试

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);
    );
);

Routes.test

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);
    );
);

商店

store.js

The Redux Chrome pluginwindow.__REDUX_DEVTOOLS_EXTENSION__ &amp;&amp; window.__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 脚本吗?那里好像出了什么问题。 @Tiddo defs!添加了商店代码... 我不是 100% 确定,但我有一种预感,`window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()` 会导致 undefined,并导致错误。您可以尝试删除该行并查看它是否仍然失败? 啊!有趣......是的,就是这样......嗯。好的,所以我需要该逻辑才能使 chrome devtools 中的 Redux 选项卡正常工作。有没有办法在开玩笑的测试中以某种方式忽略它? 或者更好:按照扩展程序本身的高级设置说明进行操作here 【参考方案1】:

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

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

【讨论】:

以上是关于为啥这些 Jest 测试失败了? TypeError:无法读取未定义的属性“应用”的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?

为啥 jest 寻找不再存在的测试文件?

为啥 Jest --runInBand 会加快测试速度?

用 Jest 测试 Vue 失败,Jest 遇到了意外的令牌,SyntaxError: Unexpected token import

如何让 Jest 静默测试抛出的错误

Jest 测试失败,未定义窗口