Open lmk123 opened 1 year ago
在写测试时,我经常需要提前准备好测试代码,比如如果我想测试下面这个模块:
// testMe.ts import otherModule from 'other-module' // 读取其它模块的值 const id = otherModule.id // 读取环境变量 const key = process.env.KEY // 读取全局变量 const ua = navigator.userAgent export function testMe() { return id + ':' + key + ':' + ua }
假设我的测试用例是这么写的:
// testMe.test.ts import { testMe } from './testMe' test('s', () => { expect(testMe()).toBe('a:b:c') })
如果就这样运行,那么 testMe() 的结果会是 undefined:undefined:undefined,怎样才能确保这个值变成我想要的 a:b:c?
testMe()
undefined:undefined:undefined
a:b:c
jest.mock
jest 会将 jest.mock 提升至所有模块 import 之前运行:
// testMe.test.ts import { testMe } from './testMe' jest.mock('other-module', () => ({ id: 'a' })) // 即使它写在 import testMe 之后,实际上它会在 import 前运行 test('s', () => { expect(testMe()).toBe('a:b:c') })
利用 setupFiles 提前准备好即可:
// jest-setup.js process.env.KEY = 'b' global.navigator = { userAgent: 'c' }
直接把代码写在 import 前是不行的。
// 虽然这两行代码写在 import testMe 前面,但实际上 testMe.ts 里的代码会先运行,因为 babel 会将 import 全提升到顶部。 // `jest.mock()` 之所以能提升到 import 前面,是因为 jest 自己开发了一个 babel 插件 // https://www.npmjs.com/package/babel-plugin-jest-hoist process.env.KEY = 'b' global.navigator = { userAgent: 'c' } import { testMe } from './testMe'
但 setupFiles 对所有测试文件都会效果。如果只想让它对部分测试文件生效,就要在 jest.config.js 里用到 projects:
// jest.config.js module.exports = { projects: [ { testMatch: ['testMe.test.ts'], setupFiles: ['jest-setup.js'] } ] }
但单独为一个 test 文件写 projects 配置比较麻烦。如果不想用 projects,还有一个办法。
前面说到 import 会被提升到代码前面,但只要我们的代码也放在一个单独的模块里,然后从 test 文件里 import 就行了:
import './testMe-prepare' // 这个文件里包含设置全局变量的代码 import { testMe } from './testMe'
在写测试时,我经常需要提前准备好测试代码,比如如果我想测试下面这个模块:
假设我的测试用例是这么写的:
如果就这样运行,那么
testMe()
的结果会是undefined:undefined:undefined
,怎样才能确保这个值变成我想要的a:b:c
?对于模块,可以用
jest.mock
jest 会将 jest.mock 提升至所有模块 import 之前运行:
对于环境变量 / 全局变量,可以用 setupFiles
利用 setupFiles 提前准备好即可:
但 setupFiles 对所有测试文件都会效果。如果只想让它对部分测试文件生效,就要在 jest.config.js 里用到 projects:
但单独为一个 test 文件写 projects 配置比较麻烦。如果不想用 projects,还有一个办法。
前面说到 import 会被提升到代码前面,但只要我们的代码也放在一个单独的模块里,然后从 test 文件里 import 就行了: