DOM 操作
非官方测试版翻译
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
另一类通常被认为难以测试的函数是直接操作 DOM 的代码。我们来看看如何测试这段 jQuery 代码:它监听点击事件,异步获取数据并设置 span 元素的内容。
displayUser.js
'use strict';
const $ = require('jquery');
const fetchCurrentUser = require('./fetchCurrentUser.js');
$('#button').click(() => {
fetchCurrentUser(user => {
const loggedText = 'Logged ' + (user.loggedIn ? 'In' : 'Out');
$('#username').text(user.fullName + ' - ' + loggedText);
});
});
同样地,我们在 __tests__/ 目录下创建测试文件:
__tests__/displayUser-test.js
'use strict';
jest.mock('../fetchCurrentUser');
test('displays a user after a click', () => {
// Set up our document body
document.body.innerHTML =
'<div>' +
' <span id="username" />' +
' <button id="button" />' +
'</div>';
// This module has a side-effect
require('../displayUser');
const $ = require('jquery');
const fetchCurrentUser = require('../fetchCurrentUser');
// Tell the fetchCurrentUser mock function to automatically invoke
// its callback with some data
fetchCurrentUser.mockImplementation(cb => {
cb({
fullName: 'Johnny Cash',
loggedIn: true,
});
});
// Use jquery to emulate a click on our button
$('#button').click();
// Assert that the fetchCurrentUser function was called, and that the
// #username span's inner text was updated as we'd expect it to.
expect(fetchCurrentUser).toHaveBeenCalled();
expect($('#username').text()).toBe('Johnny Cash - Logged In');
});
通过模拟 fetchCurrentUser.js,我们的测试无需发起真实网络请求,而是直接解析本地模拟数据。这确保测试能在毫秒级完成(而非秒级),保证单元测试的快速迭代。
此外,被测试函数在 #button DOM 元素上添加了事件监听器,因此需要为测试正确设置 DOM 环境。jsdom 和 jest-environment-jsdom 包能模拟浏览器中的 DOM 环境,这意味着所有调用的 DOM API 都会以与浏览器相同的方式被观测!
要启用 JSDOM 测试环境,需先安装 jest-environment-jsdom 包(如尚未安装):
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev jest-environment-jsdom
yarn add --dev jest-environment-jsdom
pnpm add --save-dev jest-environment-jsdom
bun add --dev jest-environment-jsdom
本示例代码可在 examples/jquery 查看。