在beforeEach中声明initialState报错:ReferenceError: initialState未定义
问题原因:函数作用域的限制
你碰到的ReferenceError: initialState is not defined是变量作用域导致的典型问题:
你在beforeEach的回调函数内部用const声明了initialState,这个变量的作用域被严格限制在beforeEach的函数体内。而每个it测试块都是独立的函数作用域,根本无法访问到beforeEach内部的这个变量。
修复方案:将变量作用域提升到
describe层级 把initialState的声明移到describe块的顶部(用let声明,因为需要后续赋值),然后在beforeEach里完成赋值操作,这样所有it测试块都能共享这个变量:
describe('register reducer', () => { // 把变量声明提升到describe作用域,所有it块都能访问 let initialState; beforeEach(() => { // 这里只需要赋值,无需再次声明 initialState = UsersService.getInitialUsersState(); }) it('should return the initial state', () => { expect(usersReducer(undefined, [])).toEqual(initialState); }); it('Toggle isBaby or sitter', () => { deepFreeze(initialState); // 注意:不能直接修改被冻结的initialState!要创建新的状态对象 const newState = { ...initialState, isBaby: true }; expect( usersReducer(initialState, { type: types.UsersActions.SET_TYPE, payload: true }) ).toEqual(newState); }); });
额外提醒:遵守Redux的纯函数原则
你原来的测试代码里还有个容易踩坑的点:调用deepFreeze(initialState)之后,还直接修改initialState.isBaby = true——这不仅会触发冻结对象的修改报错,还违背了Redux reducer的纯函数规则:reducer永远不会修改原状态,而是返回一个全新的状态对象。所以正确的做法是用对象展开语法{ ...initialState, isBaby: true }创建新状态,再和reducer的返回值做对比。
内容的提问来源于stack exchange,提问作者July333
相关产品推荐
相关产品推荐

