当我正在测试的文件开始时,如何通过从卸载的 DOM 中抓取元素来运行 Jest 中的测试?



我是测试和Jest的新手。我正试图在app6.test.js中运行一个测试。这是我的第一个测试。

期望的是,在正确运行之后,我的测试要么通过,要么失败。目前,它正在失败。我相信我知道为什么。我一会儿就到。

以下是测试失败时我得到的错误:

FAIL  maze/app6.test.js
● Test suite failed to run
TypeError: Cannot read property 'style' of null
6 | const yRows = height / cube;
7 | const cols = width / cube;
>  8 | maze.style.width = width + 'px';
|      ^
9 | maze.style.height = height + 'px';
10 | 
11 | const trees = [];
at Object.<anonymous> (maze/app6.js:8:6)
at Object.<anonymous> (maze/app6.test.js:7:37)
Test Suites: 1 failed, 1 total

所以,我认为它失败了,因为据我所知,Jest进入包含待测试代码的文件,并试图运行该文件。但在我的情况下,它不能做到这一点,因为我的文件试图加载DOM元素,而任何浏览器都没有加载DOM。

我所拥有的最接近解决方案是尝试打开使用Puppeter运行脚本的网页,然后运行函数

/**
* @jest-environment jsdom
*/
const puppeteer = require("puppeteer")
const { checkIfCellsAreAdjacent } = require("./app6");
test("should output true or false", async () => {
const browser = await puppeteer.launch({
headless: false,
})
const page = await browser.newPage();
await page.goto(`C:\Users\myName\2020-Coding-Projects\mentoring\kruskel\maze\maze-4.html`)
const boolean = checkIfCellsAreAdjacent({ x: 29, y: 30 }, { x: 30, y: 30 });
expect(boolean).toBe(true);
});

但无论我在那里做了什么,都没有奏效。

现在,我可以遍历app6.js,然后通过外科手术删除表示let maze = document.getElementById('maze');的行以及之后引用它的所有内容。但这需要经历很多代码,我宁愿把它们集成在一起。必须有一个替代方案。

回复:研究,我去过大约6-7个不同的网站,我通过谷歌搜索";jest typeerror无法读取null的属性"style";。这些链接谈论的不是特别相似的问题(尽管它们至少用同一种语言(。它们让我想到了";嘲笑";一个元素,但显然我做得不对。。。

救命!求你了,谢谢你。

编辑:所以没人需要问。。。app6.js:的前8行

let maze = document.getElementById('maze');
const height = 900;
const width = 1500;
const cube = 50 // cell size = 20px by 20px. Hence cube
const yRows = height / cube;
const cols = width / cube;
maze.style.width = width + 'px';

Jest DOM和Puppeter测试是正交的。如果是测试的实现,那么涉及puppeteer的所有内容都不属于此测试。

app6.js的问题似乎是它在顶级访问DOM,而不是需要它的函数,这需要在导入模块之前设置mock,因此它需要在测试中导入,而不是在顶级。CCD_ 3或CCD_ 4和CCD_。

maze元素需要通过模拟document.getElementById调用或将其放入DOM来进行模拟。前一个选项要求在测试后重置mock;这最好总是用CCD_ 8配置选项来完成。后者需要在测试后进行清理:

let maze;
let app6;
beforeEach(() => {
maze = document.createElement('div');
maze.setAttribute('id', 'maze');
document.body.appendChild(maze);
jest.isolateModules(() => {
app6 = require('./app6');
});
});
test("should output true or false", () => {
const boolean = app6.checkIfCellsAreAdjacent({ x: 29, y: 30 }, { x: 30, y: 30 });
expect(boolean).toBe(true);
});
afterEach(() => {
document.body.removeChild(maze);
});

我找到了一个不太完美的问题解决方案。

解决方案是将我的所有函数从app6.js移到一个单独的文件中,然后从那个单独的文件导入我想要测试的函数。这样,我就可以避免运行完全指向DOM的代码。

理想情况下有人会告诉我如何在不移动文件中代码的情况下运行:换句话说,我希望所有代码都在一个文件中运行。不过,这个解决方案目前还可以。

最新更新