【问题标题】:jest is failing to find `bota` and `atob`开玩笑没有找到 `btoa` 和 `atob`
【发布时间】:2022-05-03 01:48:06
【问题描述】:

创建一个类似的笑话测试:

test("btoa", () => {
  expect(btoa("aaa")).toStrictEqual("YWFh");
});

失败

ReferenceError: btoa is not defined

但是,node 确实从节点 16 开始定义 btoa,因此如下:

console.log(bota("aaa"))

正确输出YWFh

如何配置 jest 以通过此测试?显然,在开玩笑的测试运行器中发生了一些事情,无法在当前节点环境中执行,或者正在剥离特定的内置插件,只是我似乎找不到任何关于如何调试或调整它的文档。

更新

可以通过在“纯 js”中手动编写编码或依赖于类似的东西来解决问题,但我特别感兴趣的是为什么开玩笑的执行结尾无法找到似乎存在于其他环境。

这在 mocha 等其他测试框架中也可以正常工作,因此它显然与 jest runner 特别相关。

【问题讨论】:

    标签: javascript jestjs built-in


    【解决方案1】:

    更新

    经过大量搜索和为什么 btoa/atob 在节点中可用但不能在节点中开玩笑运行后,我终于弄明白了。 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
    

    注意:下面描述的答案仍然是“解决方案”——你需要定义这些方法在node中使用,然后你需要使用jest的globalSetup来暴露它们。


    原答案

    问题的根源在于 NodeJS 和 Web 浏览器具有不同的 API。例如,当我尝试在我的节点应用程序中使用 btoa 时,我会收到此弃用通知。

    解决方案的第一部分是您需要提供自己的atob/btoa 方法以在NodeJs 中使用(请参阅examples here)。然后你需要使用 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、phantomjs、testing-library)。这些库本质上复制了节点环境中的浏览器 API,用于运行测试、服务器端渲染等。我建议阅读 testing web frameworks 以获取代码示例和技术。

    【讨论】:

    • 问题是我想明确地使用它们以实现 Web 兼容性,因此使用节点 API 复制它们没有帮助。
    • 如果您要在节点环境中运行 Web 测试,可悲的是,这是唯一的方法。您可以使用 jests globalSetup config 进行设置。您还可以阅读有关 testing web frameworks 的信息 - 其中大部分使用某种技术来使用 Web API(phantomjs、jsdom、testing-library 等)填充节点环境。
    • 为什么这是唯一的方法?像 mocha 这样的其他测试环境可以正常工作,node 本身也是如此。如果这没有在节点中定义,我会理解,我不明白为什么 jest 会选择性地删除某些内置插件。
    • 我找到了原因 - 请参阅更新后的答案。
    • 对我来说这些特定的符号没有暴露在虚拟机中仍然很奇怪,但这确实解释了它!感谢所有的挖掘!
    猜你喜欢
    • 2017-11-28
    • 1970-01-01
    • 2021-03-19
    • 2018-12-09
    • 2018-10-12
    • 2021-05-30
    • 2021-01-01
    • 1970-01-01
    相关资源
    最近更新 更多