【问题标题】:Configuring jsdom in Jest across multiple tests without using modules在不使用模块的情况下跨多个测试在 Jest 中配置 jsdom
【发布时间】:2018-12-04 22:44:36
【问题描述】:

我想在无法导出模块的环境中测试脚本。我已经安装了 Jest 版本 23.1.0,我的 package.json 文件中没有其他软件包。 使用 jsdom 'old' api 我想出了一个按预期工作的解决方案:

script.js

var exVar = "test";

script.test.js

const jsdom = require('jsdom/lib/old-api.js');

test('old jsdom api config', function(done) {
    jsdom.env({
        html: "<html><body></body></html>",
        scripts: [__dirname + "/script.js"],
        done: function (err, window) {
            expect(window.exVar).toBe("test");
            done();
        }
    });
});

但是,对于这个实现,我必须为每个测试重新编写配置,因为看起来 jsdom 配置每次都被重新编写。

我的尝试

到目前为止,我已尝试运行此配置:

const jsdom = require('jsdom/lib/old-api.js');
jsdom.env({
    html: "<html><body></body></html>",
    scripts: [__dirname + "/script.js"],
    done: function (err, window) {
        console.log('end');
    }
});

通过这个测试:

test('old jsdom api config', function(done) {
   expect(window.exVar).toBe("test");
   done();
});

以不同的方式:在 beforeAll 内部,在通过 setupFiles 或通过 Jest 配置对象中的 setupTestFrameworkScriptFile 链接的脚本内部,但仍然没有任何作用。

也许我可以按照docs 中的建议扩展jest-environment,但我不知道应该使用的语法,也不知道如何将此文件链接到测试。

【问题讨论】:

    标签: javascript node.js jestjs jsdom


    【解决方案1】:

    感谢我的同事Andrea Talon,我找到了一种使用“标准 API”(不是“旧 API”)对不同测试(至少在同一个文件中)使用相同设置的方法。

    这是完整的测试文件。

    const {JSDOM} = require("jsdom")
    const fs = require("fs")
    
    // file to test
    const srcFile = fs.readFileSync("script.js", { encoding: "utf-8" })
    
    // the window
    let window
    
    describe('script.js test', () => {
      beforeAll((done) => {
        window = new JSDOM(``, {
          runScripts: "dangerously"
        }).window
    
        const scriptEl = window.document.createElement("script")
        scriptEl.textContent = srcFile
        window.document.body.appendChild(scriptEl)
        done()
      })
    
      test('variable is correctly working', (done) => {
        expect(window.exVar).toBe("test");
        done()
      })
    
    })
    

    其他设置

    为了加载多个脚本,我创建了这个函数,它接受一个脚本数组:

    function loadExternalScripts (window, srcArray) {
      srcArray.forEach(src => {
        const scriptEl = window.document.createElement("script")
        scriptEl.textContent = src
        window.document.body.appendChild(scriptEl)
      });
    }
    

    因此,我可以通过在文件顶部声明它们来加载它们,而不是将每个脚本附加到 window 变量,如下所示:

    // files to test
    const jQueryFile = fs.readFileSync("jquery.js", { encoding: "utf-8" })
    const srcFile = fs.readFileSync("lib.js", { encoding: "utf-8" })
    

    然后在beforeAll 函数中,我可以像这样完全加载它们:

    loadExternalScripts(window, [jQueryFile, srcFile])
    

    【讨论】:

    • 通过进一步的探索,我发现声明和配置一个新窗口是没有用的,因为 Jest 已经在后台这样做了。所以第一个require没用,声明window变量也没用,在beforeAll声明中给window赋值也没用。其他部分仍然需要。
    • 我用更新的工作配置创建了一个 GitHub 存储库:github.com/gtempesta/jest-without-modules
    • 这看起来令人生畏。这让我觉得 Jest 不是适合未格式化为模块的 js 代码的测试框架。
    猜你喜欢
    • 1970-01-01
    • 2021-08-27
    • 2020-08-26
    • 2017-05-26
    • 2017-09-27
    • 2012-12-23
    • 2020-08-30
    • 2017-06-02
    • 2019-10-31
    相关资源
    最近更新 更多