Open Jiang-Xuan opened 4 years ago
比如下列代码:
// a.js module.exports = function a() {} // b.js module.exports = function b() {} // ab.js const a = require('./a') const b = require('./b') module.exports = function ab(object) { a(object.a) b(object.b) }
你如何测试传递给 ab 的参数 object 中的 a 属性被传递给了 a 模块, b 属性被传递给了 b 模块?
比如有一个系统有一个配置文件, 这个配置文件是 commonjs 格式的, 这个配置文件也可能非常的大, 如果你对这个配置文件的校验放在了同一个函数中, 可能是这样的:
第一, 这个函数太复杂, 理解起来很麻烦
第二, 测试用例很难写, 因为你可能需要保持一个合适的配置来测试其他部分,
// ab.js function ab(object) { if (!!object.a === false) { throw new Error('缺失 a') } if (!!object.b === false) { throw new Error('缺失 b') if (!!object.b.c === false) { throw new Error('缺失 b') } } } // ab.test.js ... // 测试 object.b.c 属性是否存在 test('b', () => { const config = { a: 1, b: { c: 3 } } })
注意这里, 你必须保持 a 是可以通过的, 否则你测试不到 b.c, 函数就会抛出错误, 也就是你无法判断 b 是否能通过测试, 你必须关注 a, 所以拆分进行测试
// a.js module.exports = function a(a) {} // b.js module.exports = function b(b) {} // ab.js const a = require('./a') const b = require('./b') module.exports = function ab(object) { a(object.a) b(object.b) }
这样的拆分测试, 可以分别针对 a, b 写测试
这里 ab 成为了集成函数, 写集成测试来测试这个函数, 只用判断 object.a 被传递给了 a, object.b 被传递给了 b, 也不用测试太多的细节, 导致测试用例太过于复杂
文档 https://jestjs.io/docs/en/jest-object#mock-modules
注意: 当使用 babel-jest 的时候, 调用 jest.mock 将自动提升到代码的顶部. 所以这里可以延迟声明 jest.mock. 如果不使用 babel-jest, 需要手动提升 jest.mock
babel-jest
jest.mock
动机
比如下列代码:
你如何测试传递给 ab 的参数 object 中的 a 属性被传递给了 a 模块, b 属性被传递给了 b 模块?
举一个场景
比如有一个系统有一个配置文件, 这个配置文件是 commonjs 格式的, 这个配置文件也可能非常的大, 如果你对这个配置文件的校验放在了同一个函数中, 可能是这样的:
第一, 这个函数太复杂, 理解起来很麻烦
第二, 测试用例很难写, 因为你可能需要保持一个合适的配置来测试其他部分,
注意这里, 你必须保持 a 是可以通过的, 否则你测试不到 b.c, 函数就会抛出错误, 也就是你无法判断 b 是否能通过测试, 你必须关注 a, 所以拆分进行测试
这样的拆分测试, 可以分别针对 a, b 写测试
这里 ab 成为了集成函数, 写集成测试来测试这个函数, 只用判断 object.a 被传递给了 a, object.b 被传递给了 b, 也不用测试太多的细节, 导致测试用例太过于复杂
Answer