如何沙箱 Jest 测试

cyb*_*bat 5 node.js jestjs

根据 Jest 文档:

“每个测试的沙盒测试文件和自动全局状态重置,因此两个测试不会相互冲突。”

然而我的测试有冲突。

代码:

// Note: op is from object-path module for deep access by dot path
let config = { name: 'Bob' }

const getConfig = path => {
  return op.get(config, path) 
}

const setConfig = (path, value) => {
  return op.set(config, path, value)
}
Run Code Online (Sandbox Code Playgroud)

测试:

test('setConfig() updates a deep config value', () => {
  const { setConfig, getConfig } = require('services/config')

  setConfig('name', 'Woot')
  const res = getConfig('name')
  expect(res).toBe('Woot')
})

test('getConfig() updates a deep config value', () => {
  const { getConfig } = require('services/config')

  const res = getConfig('name')
  expect(res).toBe('Bob') // Actually Woot
})
Run Code Online (Sandbox Code Playgroud)

第一个测试修改了配置文件,导致第二个测试失败。

根据我的经验,诸如此类的事情process.env不会被沙箱化,但是这个?我对“沙盒”有什么不理解的地方?

mih*_*hai 8

默认情况下,Jest 中的沙箱似乎仅适用于文件,而不适用于同一文件中的单独测试。

这是因为 Jest 默认情况下不会取消缓存模块。

但是它确实提供了一个函数,jest.resetModules您可以在每次测试之前调用该函数:

beforeEach(() => {
  jest.resetModules()
});
Run Code Online (Sandbox Code Playgroud)

这将取消缓存您的模块并启用沙箱。
您还可以通过以下设置来配置 JestresetModulespackage.json

{
  "name": "my-project",
  "jest": {
    "resetModules": true
  }
}
Run Code Online (Sandbox Code Playgroud)

要利用这些设置,您需要require在每个测试中使用您的模块(您已经在这样做)。我只是提到这一点,因为即使您调用了,如果文件顶部jest.resetModules有一个,您的测试也会失败。require