简体   繁体   English

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

[英]How do I run a test in Jest when the file I'm testing starts by grabbing an element from the unloaded DOM?

I am new to testing and Jest.我是测试和开玩笑的新手。 I am trying to run a test in app6.test.js.我正在尝试在 app6.test.js 中运行测试。 It's my first one.这是我的第一个。

The expectation is that my test either passes or fails after running correctly .期望是我的测试在正确运行后通过或失败。 Currently, it's failing.目前,它正在失败。 I am confident that I know why.我有信心知道为什么。 I'll get to that in a sec.我会在几秒钟内解决这个问题。

Here is the error I get when the test fails:这是测试失败时我得到的错误:

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

So, I believe it's failing because, as I understand it, Jest goes into the file containing the to-be-tested code, and tries to run the file.所以,我相信它失败了,因为据我了解,Jest 进入包含待测试代码的文件,并尝试运行该文件。 But in my case it can't do that because my file tries to load a DOM element, and there is no DOM loaded by any browser.但在我的情况下,它不能这样做,因为我的文件试图加载一个 DOM 元素,并且任何浏览器都没有加载 DOM。

The closest thing I have to a solution is trying to open the webpage which runs the script using Puppeteer, and then running the function:我最接近解决方案的方法是尝试打开使用 Puppeteer 运行脚本的网页,然后运行 function:

/**
 * @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);
});

But whatever I did there, it didn't work.但无论我在那里做什么,它都没有奏效。

Now, I could go through app6.js and surgically remove the line that says let maze = document.getElementById('maze');现在,我可以通过 app6.js 删除 go 并通过手术删除let maze = document.getElementById('maze');的行。 and everything that references it afterwards.以及之后引用它的所有内容。 But that requires going thru a lot of code that I'd rather leave integrated.但这需要通过大量我宁愿保持集成的代码。 There must be an alternative.必须有替代方案。

Re: research, I've been to about 6-7 different sites that I found by googling "jest typeerror cannot read property 'style' of null".回复:研究,我去过大约 6-7 个不同的网站,通过谷歌搜索“开玩笑的 typeerror 无法读取 null 的属性 'style'”。 These links talk about, eeeh, not particularly similar problems (though they are in the same language at least).这些链接谈论,eeeh,不是特别相似的问题(尽管它们至少使用相同的语言)。 They lead me to the concept of "mocking" an element but apparently I didn't do it correctly...他们把我引向了“嘲笑”一个元素的概念,但显然我没有正确地做到这一点......

Help.帮助。 Please and thank you.谢谢,麻烦您了。

Edit: so no one has to ask... the top 8 lines of app6.js:编辑:所以没有人要问... 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 and Puppeteer tests are orthogonal. Jest DOM 和 Puppeteer 测试是正交的。 If it's the implementation that is tested, everything that involves puppeteer doesn't belong to this test.如果是被测试的实现,所有涉及puppeteer的东西都不属于这个测试。

It appears that the problem with app6.js is that it accesses DOM on top level rather than functions that need it, this requires mocks to be set up before the module is imported, so it needs to be imported inside a test rather that on top level.看来 app6.js 的问题在于它访问顶层的 DOM 而不是需要它的函数,这需要在导入模块之前设置模拟,因此需要在测试中导入它而不是在顶层等级。 jest.isolateModules or a combination of require and jest.resetModules is appropriate to test a module without interfering with other tests. jest.isolateModulesrequirejest.resetModules的组合适用于在不干扰其他测试的情况下测试模块。

maze element needs to be mocked, either by mocking document.getElementById call or by putting it to DOM. maze元素需要通过 mocking document.getElementById调用或将其放入 DOM 来模拟。 The former option requires to reset the mock after a test;前一个选项需要在测试后重置模拟; this should be preferably done always with restoreMocks configuration option.最好始终使用restoreMocks配置选项来完成此操作。 The latter requires to clean up after a test:后者需要在测试后进行清理:

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);
});

I found a less-than-perfect solution to my problem.我找到了一个不太完美的解决方案来解决我的问题。

The solution was to move all my functions from app6.js to a separate file, then import the function I want to test from that separate file.解决方案是将我的所有函数从 app6.js 移到一个单独的文件中,然后从那个单独的文件中导入我想测试的 function。 That way I avoid running the code that reaches out to the DOM entirely.这样我就可以避免运行完全触及 DOM 的代码。

Ideally someone will tell me how to run the code without moving code around in my files: in other words, I want it all to run in one file.理想情况下,有人会告诉我如何运行代码而不在我的文件中移动代码:换句话说,我希望它全部在一个文件中运行。 However this solution is OK for now.但是,此解决方案目前还可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用(substack)磁带模块进行测试时,如何在文件中只运行一个测试? - When using (substack's) Tape module for testing, how do I run only one test in a file? 如何配置 playwright-jest 以排除运行的测试套件(规范)文件? - How do I configure playwright-jest to exclude a Test Suite (spec) file for a run? 开玩笑时出现错误,我尝试运行测试 - Error on jest when I try to run the test Jest + React 测试库:如何从某个库中模拟出只影响一个测试块的方法 - Jest + React Testing Library: how do I mock out a method from some library that only affects one test block 如何在我正在测试 Nestjs/jest 的同一个 class 中模拟方法 - How to mock a method in the same class I'm testing in nestjs/jest 使用Jest测试Typescript,如何测试内部函数? 我的导入/导出使我失败 - Testing Typescript with Jest, how do I test an internal function? My import/export is failing me 使用 Jest,在 vue.js 中对单个文件组件进行单元测试时如何窥探扩展组件的方法 - Using Jest, how do I spyon an extended component's method when unit testing a single file component in vue.js 如何在 Jest 中测试 axios? - How do I test axios in Jest? 如何使用 jest 测试函数 - How do I test functions using jest 我如何测试(开玩笑)以期待回报? - How do I test (jest) to expect return?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM