Redux警告仅出现在测试中

时间:2017-04-12 16:34:29

标签: reactjs redux react-redux create-react-app

我用react redux制作了一个tic tac toe游戏。

我正在使用create-react-app

我有以下商店:

import {createStore, combineReducers} from 'redux';
import gameSettingsReducer from './reducers/gameSettings.js';
import gameStatusReducer from './reducers/gameStatus.js';


const rootReducer = combineReducers({gameSettings: gameSettingsReducer,
                   gameStatus: gameStatusReducer});

export const defaultGameStatus = {
      currentPlayerSymbol: "X",
      turnNumber: 0,
      currentView: "start-menu", //one of "start-menu", "in-game", "game-over"
      winner: "draw", //one of "X", "O", "draw"
      board: [["E", "E", "E"],
              ["E", "E", "E"],
              ["E", "E", "E"]],
      lastMove: []
};

const store = createStore(rootReducer, {
    gameSettings:{
        playerSymbol: "X",  //one of "X", "O"
        difficulty: "easy"  //one of "easy", "hard"
    },
    gameStatus: defaultGameStatus
});


export default store;

一切都按照我的预期运行。除了我运行测试(npm test)时,控制台中会出现以下内容:

console.error node_modules\redux\lib\utils\warning.js:14
  No reducer provided for key "gameStatus"
console.error node_modules\redux\lib\utils\warning.js:14
  Unexpected key "gameStatus" found in preloadedState argument passed to createStore. Expected to find one of the known reducer keys instead: "gameSettings". Unexpected keys will be ignored.

在我的几个测试中,我甚至没有测试商店。所以我想在编译代码时会出现这种情况。 我尝试将console.log(gameStatusReducer)放在根减速器行之前。 它表明gameStatusReducer未定义。

由于gameSettingsReducer和gameStatusReducer都以非常相似的方式创建,我不知道这个错误来自何处,甚至不知道如何进一步调查此问题。这仅在运行测试时显示。运行应用程序不会显示此问题,应用程序按预期工作。

所以,问题是:

  • 为什么这只是出现在测试中?
  • 如何调查问题的来源?

5 个答案:

答案 0 :(得分:14)

经过大量的敲击键盘后,我发现了一些线索。

快速解决方法export而不是gameStateReducer制作正常default,并使用import { gameStateReducer } from // ...将其导入其他位置。

Jest会对某些导入进行自动模拟,显然在这种情况下会出现问题,或者它需要react-create-app未提供的某种配置。

至于为什么Jest甚至记录了这个错误(考虑到相关代码没有在任何测试中导入),我想这是由于它的内部工作原理。

支持这一点有以下证据:向--testPathPattern脚本添加npm test标记仅匹配以.test.js结尾的文件不会改变行为,但仍会出现错误。

如何调查问题:我首先弄清楚导致错误日志的代码是否在测试中(间接可能是这样,例如import )。在排除这一点之后,我开始模拟传递给combineReducers的函数,以确保任何更改都会影响错误日志的结果,并且确实如此。只需添加:

gameStatus: gameStatusReducer || (() => ())

...已经解决了这个问题,这意味着import以及Jest / babel-jest如何处理它是错误的。

如果我要进一步调查此问题,我会使用Jest创建自己的安装并提供我自己的配置,以查看Jest是否仍然编译整个应用程序。如果使用react-create-app,将配置选项传递给Jest似乎并非易事。

祝你好运!

答案 1 :(得分:10)

也有此错误,但使用的是TypeScript。

为了论证,我们说错误是No reducer provided for key "favourites"

对于导致此错误的测试,我们从该reducer的文件中导入了一个接口,该接口显然会运行该文件以生成导出。

我们的favourites reducer导入我们的Redux存储,以查询该状态的另一部分,作为其一个切换案例的一部分。

出于某种原因,评论我们访问Store.getState().someOtherReducersState的行会导致错误消失。

因此修复只是在测试文件中jest.mock('../route/to/Store');导致错误输出。

答案 2 :(得分:0)

我也有此错误,原因与上面的评论相同,但我以更明智的方式解决了该问题:

将模块文件分成两个文件,一个用于减速器,一个用于动作(而不是包含两个文件)

答案 3 :(得分:0)

就我而言,事实证明其中一个模块存在循环依赖(它导入了整个 state

答案 4 :(得分:-3)

组合reducer,确保import VoxImplant from 'react-native-voximplant'; 而不是juste将它们合并到一个对象中并将其提供给createStore。

例如:

import { combineReducers } from 'redux';