暗黑模式单元测试应聚焦js逻辑验证:模拟matchmedia和localstorage,覆盖主题检测、切换、持久化及dom更新,不测css、浏览器api或ui交互。

对暗黑模式切换写单元测试,核心是验证 JavaScript 逻辑是否正确读取、设置和响应系统或用户偏好变化,而不是测试 CSS 或浏览器 API 的实现本身。重点覆盖:检测当前主题、监听系统偏好变更、手动切换主题、持久化存储(如 localStorage)更新、以及 DOM 类名或属性是否按预期修改。
模拟 matchMedia 和 localStorage
暗黑模式常依赖 window.matchMedia('(prefers-color-scheme: dark)') 获取系统偏好,还需读写 localStorage 记住用户选择。单元测试中需用 Jest 或 Vitest 模拟它们:
- 用
Object.defineProperty(window, 'matchMedia', {...})模拟返回不同匹配状态的MediaQueryList对象 - 用
jest.mock('localStorage', ...)或直接替换Storage.prototype.getItem/setItem来控制初始值和捕获调用 - 例如:让首次调用
matchMedia返回{ matches: false }(亮色),后续手动触发mediaQueryList.dispatchEvent(new Event('change'))模拟系统切换
测试主题检测与初始化逻辑
验证初始化函数能否正确组合“用户设置”和“系统偏好”,得出最终主题:
- 当
localStorage为空且系统为dark→ 应启用暗黑模式 - 当
localStorage存有'light'→ 忽略系统偏好,强制亮色 - 当
localStorage存有'auto'→ 行为回退到系统偏好 - 检查是否给
或正确添加了data-theme="dark"或class="dark"
测试切换函数与事件响应
对暴露的 toggleTheme()、setTheme('dark') 等函数做行为验证:
- 调用
setTheme('dark')后,localStorage是否存入'dark' -
document.documentElement.dataset.theme是否变为'dark' - 再次调用
toggleTheme()是否切换回'light',且 DOM 和存储同步更新 - 监听
matchMedia的change事件后,若当前为'auto',是否自动更新主题并刷新 DOM
避免测试不可控外部行为
不测以下内容,否则测试脆弱且无必要:
- CSS 变量是否生效(那是 E2E 或视觉回归的事)
- 浏览器原生
matchMedia的返回值是否准确(它由环境决定,应被模拟) - 用户点击按钮的 UI 流程(那是组件测试范畴,如用 React Testing Library 测按钮交互)
- 页面加载时的完整生命周期(只需测你的 JS 函数在给定输入下的输出和副作用)
只要逻辑拆解清晰、副作用可观察(DOM 属性、localStorage、事件监听),暗黑模式的 JS 切换逻辑就能写出稳定、快速、高覆盖的单元测试。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











