编写测试
由于你写的大部分 Redux 代码是函数,而且其中大部分是纯函数,所以很好测,不需要模拟。
#
准备工作我们推荐使用 Jest) 作为测试引擎,需要注意的是 Jest 运行在 Node 环境中,因此你不能访问 DOM。
如果想要和 Babel 一起使用,还需要安装 babel-jest
并且在 .babelrc
中通过 babel-preset-env 来配置
然后,在 package.json
中的 scripts
处添加相关的命令
执行 npm test
可以运行一次测试,执行 npm run test:watch
可以让每当文件改变时自动执行测试。
#
测试 Action Creators在 Redux 中,action creators 是返回普通对象的函数,当我们测试 action creators 时,我们想要测试是否调用了正确的 action creator 以及是否返回了正确的 action。
#
示例可以这样来测试:
#
测试异步 Action Creators对于使用 Redux-Thunk 或者其它中间件的异步 action Creator ,最好完全模拟 Redux store 来进行测试,可以通过使用 redux-mock-store 来把中间件应用于模拟的 store,还可以使用 fetch-mock) 来模拟 HTTP 请求。
#
示例可以这样来测试:
#
测试 ReducersReducer 把 action 应用到之前的 state,并返回新的 state。示例如下。
#
示例可以这样来测试:
#
测试组件React 组件有一个优点,它们通常很小且只依赖于传入的 props
,因此测试起来很简便。
首先,我们需要安装 Enzyme ,Enzyme 底层使用了 React Test Utilities ,但是更方便,更具可读性,更强大。
为了兼容 React 的版本,我们还需要安装 Enzyme 适配器,Enzyme 提供了适配器用以兼容 React16
,React 15.x
,React 0.14.x
,React 0.13.x
。如果你使用的是 React16,你可以使用下面的命令安装相关依赖:
为了测试组件,我们创建了一个 setup()
辅助函数,用来把模拟过的(stubbed)回调函数当作 props 传入,然后使用 (React Shallow Rendering) 来渲染组件。这样就可以依据 “是否调用了回调函数” 的断言来写独立的测试。
#
示例上面的组件可以这样来测试:
#
测试 connected 组件如果你使用类似 React redux 的库,你可能会使用 高阶组件,比如 connect()
。可以让你把 Redux state 注入到常规的 React 组件中。
考虑如下 App
组件
在单元测试中,通常会这样导入 App
组件:
不过,上面这样导入的是通过 connect()
方法返回的包装组件,并非 App
组件本身,如果你想测试和 Redux 的整合,这很容易,通过 <Provider>
包裹它后传入用以单元测试的特殊 store 就可以了。但是有时候我们想测试的其实是不带 Redux store 的组件的渲染。
为了测试 App 组件本身而不用处理装饰器,我们推荐你导出未装饰的组件:
由于默认导出的组件依旧是包装过的组件,上面代码中的导入依旧会生效,无须你更改已有的代码。不过现在你可以通过下面这样的办法导入未装饰的组件了:
如果你需要导入二者,可以按下面这样做:
在 app 中,仍然正常地导入:
只在测试中使用命名导出。
混用 ES6 模块和 CommonJS 的注意事项
如果在应用代码中使用 ES6,但在测试中使用 ES5,Babel 会通过其
interop
机制处理 ES6 的import
和 CommonJS 的require
,使得这两种模式能一起使用,但其行为依旧有细微的区别。 如果在默认导出的附近增加另一个导出,将导致无法默认导出require('./App')
。此时,应代以require('./App').default
#
对中间件的测试中间件函数包装了 Redux 中 dispatch
的行为,为了测试中间件的行为,我们需要模拟 dispatch
调用时的行为。
#
示例首先,我们需要创建一个中间件函数,下述代码和 redux-thunk 类似
我们需要创造一个假的 getState
,dispatch
和 next
函数,我们可以使用 jest.fn()
来创建 stubs,你也可以使用 sinon 等测试框架
我们可以像 Redux 一样来触发函数
然后我们在适当的时机通过调用 getState
,dispatch
,next
函数来测试中间件。
在一些情况下,你需要修改 create
函数来模拟不同的 getState
和 next
。
#
词汇表- Enzyme: Enzyme 是一种用于 React 测试的 JavaScript 工具,它使得断言、操作以及遍历你的 React 组件的输出变得更简单。
- React Test Utilities :React 提供的测试工具,被 Enzyme 使用
- shallow renderer: shallow renderer 使你可以实例化一个组件, 并有效地获取其
render
方法的结果, 其渲染深度仅一层, 而非递归地将组件渲染为 DOM。 shallow renderer 对单元测试很有用, 你只要测试某个特定的组件,而不用管它的子组件。这也意味着,更改子组件不会影响到其父组件的测试。如果要测试一个组件和它所有的子组件,可以用Enzyme's mount()
方法 ,这个方法会进行完全的 DOM 渲染。