Created
November 9, 2020 08:14
-
-
Save rikumi/62c21675b5c6861926e28e2d7b1709f3 to your computer and use it in GitHub Desktop.
Jest Moebius
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 生成莫比乌斯对象 | |
* - 生成的对象支持调用,支持属性存取,支持数学运算,支持 await | |
* - 生成的对象是一个 jest.fn(),可以正常取 mock,可以正常 expect | |
* - 可以通过传入对象,自定义一些属性的值/实现 | |
* - 从莫比乌斯对象中取出和返回的值默认都是新的莫比乌斯对象,重复取出的同名对象相等 | |
* @param {any} extensions | |
* @return {any} | |
*/ | |
const createMoebius = (extensions = {}) => { | |
return new Proxy(jest.fn(() => createMoebius()), { | |
get(target, key) { | |
// 兼容 toString | |
if (key === 'toString') { | |
return () => 'MOEBIUS_OBJECT'; | |
} | |
// 兼容 valueOf,支持四则运算 | |
if (key === 'valueOf') { | |
return () => 42; | |
} | |
// 兼容 await,防止被鸭子类型判断当作 Promise 导致死等 | |
if (key === 'then') { | |
return undefined; | |
} | |
// 避免被 jest 判断为 spy 导致 toBeCalledWith 判断出错 | |
// https://github.com/facebook/jest/blob/4f84f6/packages/expect/src/spyMatchers.ts#L1150 | |
if (key === 'calls') { | |
return undefined; | |
} | |
// 兼容 mock function 中本来的字段,例如 mock | |
if (key in target || typeof key !== 'string') { | |
return target[key]; | |
} | |
// 根据传入的对象增加定制化的属性 | |
if (key in extensions) { | |
return extensions[key]; | |
} | |
// 其他情况下创建新的莫比乌斯对象,并保存下来,下次再取同一个 key,要得到同一个 value | |
return target[key] = createMoebius(); | |
}, | |
set(target, key, value) { | |
target[key] = value; | |
return true; | |
}, | |
}); | |
}; | |
module.exports = createMoebius; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment