我做了一个简单的测试来检查背景颜色是否发生变化
/**
* @jest-environment jsdom
*/
const fs = require('fs');
const path = require('path');
const html = fs.readFileSync(path.resolve(__dirname, '../index.html'), 'utf8');
describe('Testing script.js', () => {
let js
beforeEach(()=>{
document.documentElement.innerHTML = html.toString();
js = require('../script');
})
afterEach(() => {
document.documentElement.innerHTML = '';
});
test('Button click changes output content', () => {
const myButton1 = document.getElementById('button-test1')
const output = document.getElementById('output')
const outputBefore = output.textContent
myButton1.click()
const outputAfter = output.textContent
expect(outputBefore).not.toBe(outputAfter)
});
test('changes background colour', () => {
const myButton2 = document.getElementById('button-test2')
document.body.style.backgroundColor = 'blue'
const bodyBefore = document.body.style.backgroundColor
console.log(bodyBefore)
myButton2.click()
const bodyAfter = document.body.style.backgroundColor
console.log(bodyAfter)
expect(bodyBefore).not.toBe(bodyAfter)
});
});
const myButton1 = document.getElementById('button-test1')
const myButton2 = document.getElementById('button-test2')
myButton1.addEventListener('click', () => clickEvent1())
myButton2.addEventListener('click', () => clickEvent2())
function clickEvent1() {
console.log("clickEvent1")
const element = document.getElementById('output')
if (element.textContent === "") element.textContent = "Hello World"
}
function clickEvent2() {
console.log("clickEvent2")
if (document.body.style.backgroundColor != 'red') document.body.style.backgroundColor = 'red'
}
第二个测试失败,但是当单独运行时,测试工作正常。起初我认为这是因为同一个按钮被单击了两次,但这些是单独的元素。我不认为测试本身有问题,我无法解决。
我尝试使用 beforeEach/afterEach() 来拆解 html,希望在测试之间“重置”JSDOM。
这对我来说毫无意义,并且破坏了我对 Jest 工作原理的理解。
任何人都可以解释这种行为吗?
问题
第二次测试中的单击事件未触发。
行为解释
当 Jest 通过 require 函数加载模块时,该模块会缓存在注册表中并执行。因此,第二次测试之前的 require('../script') 行不会加载或执行脚本,因为该模块已存在于注册表中。这意味着当您在第二次测试之前重置 DOM 时,最初注册的事件处理程序都不会附加到新 DOM 中的新元素。
您的问题有两种基本解决方案。
笑话文档: jest.resetModules()
在上面的示例代码中,一种可能的解决方案是删除 afterEach 代码块并更新 beforeEach 代码块。
beforeEach(() => {
document.documentElement.innerHTML = html.toString();
// Reset module registry
jest.resetModules();
js = require('../script');
});
你不需要 afterEach,这会导致问题