gpt4 book ai didi

javascript - JSDOM - 文档未定义

转载 作者:行者123 更新时间:2023-12-02 23:17:23 25 4
gpt4 key购买 nike

我创建了一个非常简单的页面,仅显示一条消息,因为我正在尝试测试 JSDOM 以使用 document。但是,我收到以下错误。

首先,我在网上看到了无数的例子,除了Stack Overflow上发布的问题,但我连最简单的例子都无法解决。顺便说一句,我是 Javascript 新手。

到目前为止我的代码如下:

根目录

--->index.html
--->module.js
--->package-lock.json
--->package.json
--->测试
--->--->messageTest.js

不同的文件如下:

index.html

<!doctype html>
<head>
<meta charset="utf-8">
<title>jsdom Unit Test</title>
</head>

<body>
<p id='msg'>Hello, World!</p>
<script src="module.js"></script>
</body>
</html>

module.js

function updateMsg(newMsg) {
document.getElementById('msg').innerHTML = newMsg;
}

updateMsg("Changing message");

module.exports = updateMsg;

package.json

{
"name": "message-example",
"version": "1.0.0",
"description": "Testing how to use the JSDOM",
"main": "module.js",
"scripts": {
"test": "mocha"
},
"author": "",
"license": "ISC",
"devDependencies": {
"chai": "^4.2.0",
"jsdom": "^15.1.1",
"mocha": "^6.2.0",
"mocha-jsdom": "^2.0.0",
"rewire": "^4.0.1",
"sinon": "^7.3.2"
}
}

messageTest.js

var updateMsg = require('../module.js');
const expect = require('chai').expect
const { JSDOM } = require('jsdom');

describe('updateMsg', function () {

before(function() {
return JSDOM.fromFile('index.html')
.then((dom) => {
global.window = dom.window;
global.document = window.document;
});
})

it ('updates the innerHTML of element with id "msg"', function () {
expect(document.getElementById('msg').innerHTML).to.equal('Hello, World!');
updateMsg('The new msg!');
expect(document.getElementById('msg').innerHTML).to.equal('The new msg!');
});
});

如果我使用 npm test 运行测试,我会在 document.getElementByID... 处收到 ReferenceError:文档未定义 错误> 进入 module.js 文件。

如果我删除 updateMsg("Changing message"),我的测试显然运行良好。

最佳答案

该示例中存在几个问题:

  1. 您正在混合 jsdom 窗口和全局节点上下文。避免分配给 global (因为这样更容易犯错误),不要 require() 您想要在虚拟窗口中运行的脚本。

  2. jsdom 默认情况下会阻止运行页面脚本,因此您的 module.js 既不会加载也不会执行。您必须提供 { resources: "usable", runScripts: "outside-only"} 参数来解决此问题(请务必阅读 jsdom README 中的安全隐患)。

  3. 您没有等待 load 事件,因此您的测试会在 jsdom 有机会加载脚本之前运行。

工作代码看起来像这样:

const expect = require("chai").expect;
const { JSDOM } = require("jsdom");

describe("updateMsg", function() {
let jsdom;
before(async function() {
jsdom = await JSDOM.fromFile("index.html", {
resources: "usable",
runScripts: "dangerously"
});
await new Promise(resolve =>
jsdom.window.addEventListener("load", resolve)
);
});

it('updates the innerHTML of element with id "msg"', function() {
expect(jsdom.window.document.getElementById("msg").innerHTML).to.equal(
"Hello, World!"
);
jsdom.window.updateMsg("The new msg!");
expect(jsdom.window.document.getElementById("msg").innerHTML).to.equal(
"The new msg!"
);
});
});

您还需要从 module.js 中删除模块行,浏览器中不存在 module

关于javascript - JSDOM - 文档未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57113871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com