Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest 如何在 import 模块前运行代码 #116

Open
lmk123 opened this issue Nov 16, 2022 · 0 comments
Open

Jest 如何在 import 模块前运行代码 #116

lmk123 opened this issue Nov 16, 2022 · 0 comments
Labels

Comments

@lmk123
Copy link
Owner

lmk123 commented Nov 16, 2022

在写测试时,我经常需要提前准备好测试代码,比如如果我想测试下面这个模块:

// 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

对于模块,可以用 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

利用 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'
@lmk123 lmk123 added the Jest label Nov 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant