[笔记]jest 使用体验

最近在公司的项目里引入了 jest, 花了一段时间补充了各种用例, 由于是第一次正式使用 jest, 也遇到了一些问题, 写一篇笔记记录一下.

snapshot

对于大多数组件, jest 提供的 snapshot 都是一种很便利的工具. 只要能确定生成快照时的状态时正确的, 那么就可以比较轻易的发现修改扩大了影响范围的场景.

因此, 我们想要的结果自然是当一个组件没有被改变, 对应的 snapshot 每次生成也不会改变. 然而有一些因素可能会导致每次生成的snapshot 都不一样, 我们就遇到了两种情形:

相对时间

组件中可能会有与当前时间相关的逻辑, 比如今天生成的 snapshot 里, 时间的描述是 “1天前”, 那等到明天重新生成快照时, 时间就会变成了 “两天前”.

为此, 我们引入了 mockdate 的模块, 它会复写 window.Date, 使当前时间固定在某一时刻.

styled-components

styled-components 生成的元素, 在生成快照时会出现一个随机字符串的 className, 这个 className 会随着样式改变而变化. 然而我们是没有办法区分随机字符串的变化是否是我们期待的.

所幸 styled-components 提供了 jest-styled-components 来解决这个问题. 它会把生成的 css 也放在快照里, 这样是否是期待的变化就一目了然了.

typescript

我们的代码迁移到了 typescript上. 因此需要 ts-jest 进行 transform.

此外, 还需要在配置文件里将 mapcoverage 设置为 true, 否则计算覆盖率时生成的统计数据与代码是不匹配的.

上下文问题

有时候我们会单独测试一个包含了 react-router 的 <Link> 却没有被 withRouter 修饰的组件.

这时会抛出一个异常

1
you should not use link outside a router jest

按照 react-router 官方文档关于测试的说法, 我们可以在测试组件外包裹一个 StaticRouterMemoryRouter.

另外, react-router 每次构建 snapshot 会生成一个随机的 entries.key, 导致快照结果每次构建不相同, 需要手动指定 key

1
<MemoryRouter initialEntries={[{ key: 'AnyNotEmptyString' }]}>

Redux Store

  1. 通过 shallow 第二个参数传入 {context: store}

  2. 被 connect() 修饰的组件, 可以通过 .WrappedComponent 获取原始组件, 替换 redux 的实现