创建一个有趣的测试,如:
test("btoa", () => {
expect(btoa("aaa")).toStrictEqual("YWFh");
});失败与
ReferenceError: btoa is not defined但是,node在节点16处确实定义了btoa,因此如下所示:
console.log(bota("aaa"))正确输出YWFh。
我如何配置jest才能通过这个测试?显然,在jest测试运行程序中发生了一些事情,无法在当前节点环境中执行,或者正在剥离特定的内置程序,只是我似乎找不到任何关于如何调试或调整这些内容的文档。
更新
通过手动用“纯js”或依赖于类似的东西来编写编码,有些工作是有意义的,但我特别感兴趣的是,为什么jest执行结束没有找到似乎在其他环境中存在的内置程序。
这在其他测试框架(如mocha )中也很好,因此它显然与jest runner特别相关。
发布于 2022-02-02 19:58:40
更新
在对为什么btoa/atob在节点中可用而在节点中的jest中不可用的问题进行了大量的搜索和绞尽脑汁之后,我终于想出了答案。Jest在vm中运行所有测试,这是一个孤立的沙箱环境。btoa/atob方法不会在VM内部的global对象上自动公开。最好的例子是:
const vm = require('vm');
// this works outside the vm - but for legacy reasons only
// you shouldn't be doing this in the first place
btoa('aaa'); // -> "YWFh"
const context = vm.createContext({});
const code = 'btoa("aaa")';
vm.runInContext(code, context); //-> Uncaught ReferenceError: btoa is not defined注意:下面描述的答案仍然是“解决方案”--您需要定义这些方法以便在节点中使用,然后需要使用jest的
globalSetup公开它们。
原始答案
问题的根源在于NodeJS和web浏览器有不同的API。例如,当我试图在我的节点应用程序中使用btoa时,我会得到这个不推荐的通知。

解决方案的第一部分是需要提供自己的atob/btoa方法,以便在NodeJs中使用(参见这里的例子)。然后,您需要使用jest的globalSetup配置使其可用:
/** Encodes a string as base64 format */
global.btoa = (str: string) => Buffer.from(str, 'binary').toString('base64');
/** Decodes a base64 encoded string */
global.atob = (str: string) => Buffer.from(str, 'base64').toString('binary');如果你觉得自己不舒服的话,有一些库和工具为你服务(jsdom,幻影If,测试库)。这些库本质上是在节点环境中复制浏览器API,用于运行测试、服务器端呈现等。我建议阅读有关测试web框架的代码示例和技术。
https://stackoverflow.com/questions/70960157
复制相似问题