/ jest

使用jest + jsdom测试动态加载js文件的临时解决方法

问题背景

动态加载js文件是一个很常见的做法,但是使用jest内置的jsdom环境加载js文件,却无法捕获script的load事件,导致超时。

有什么办法呢?

解决方法

首先,根据jsdom的官方文档,jsdom是支持动态加载js的。

https://github.com/jsdom/jsdom#asynchronous-script-loading

另外,根据stackoverflow上咨询的问题来看,jsdom也能够正常抛出load事件的。

但是,我的环境下始终无法测试成功。

最后,使用了一个临时解决方法:

  • 1). 重新创建一个jsdom环境。
  • 2). 将新环境的document传给动态加载方法
  • 3). 动态加载js
  • 4). 新加载的js的全局变量会被赋值到新环境的window中
  const url = "samplejs.js";
  const index = "src/utils/sample-index.html";

  // 1. 创建一个新的jsdom环境
  const dom = await JSDOM.fromFile(index, { runScripts: "dangerously", resources: "usable" });
  const doc = dom.window.document;

  // 2. 将新环境的document传给动态加载方法
  setDocumentWrapper(doc);
  
  // 3. 动态加载js
  await loadJsAsync(url);
  
  // 4. 检查新环境的window中是否包含新变量
  expect(dom.window.sample_js).toBe(true);

其中loadJsAsync的代码参考:

《#JavaScript 根据需要动态加载脚本并设置自定义参数》
https://xmanyou.com/javascript-dynamically-load-script-and-set-parameters/