JavaScript测试蓝牙扫描需Mock API:用jest/vitest模拟navigator.bluetooth,覆盖requestDevice和watchAdvertisements;辅以HTTPS真实环境手动验证;并测试超时、错误及兼容性限制。

JavaScript 中测试蓝牙设备扫描异步结果,核心是模拟 requestDevice() 或 watchAdvertisements() 等 API 的行为,因为真实蓝牙操作受浏览器权限、硬件和安全策略(如仅允许在安全上下文、用户手势触发)限制,无法在普通测试环境直接调用。
使用 Mock 模拟 Bluetooth API 行为
在单元测试(如 Jest、Vitest)中,通过全局替换 navigator.bluetooth 为可控的 mock 对象,让扫描逻辑能稳定触发回调或返回 Promise 结果:
- 手动 mock
requestDevice,让它 resolve 一个伪造的BluetoothDevice,包含预设的id、name和gatt属性 - 对
watchAdvertisements,mock 返回一个可控制的AsyncIterator或用ReadableStream模拟广告数据流,便于测试多次扫描事件 - 注意还原 mock(例如 Jest 的
afterEach(() => jest.restoreAllMocks())),避免测试间污染
利用真实设备 + 手动触发 + 日志验证(E2E 辅助测试)
端到端测试无法完全自动化扫描,但可通过人工辅助方式验证逻辑正确性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 在 HTTPS 页面中,用真实按钮触发
navigator.bluetooth.requestDevice(),确认弹窗出现且能选中设备 - 在成功回调中打印
device.name、device.id及event.device.name(来自advertisementreceived),核对是否与预期蓝牙设备一致 - 用
console.timeLog或自定义日志标记扫描开始/结束时间,辅助判断异步流程是否卡住或超时
测试超时、拒绝、无设备等边界情况
真实场景下扫描常失败,需专门覆盖异常路径:
立即学习“Java免费学习笔记(深入)”;
- mock
requestDevice抛出"NotFoundError"(无适配器)、"SecurityError"(非安全上下文)或用户点击取消("AbortError") - 模拟空扫描结果:让 mock 的
watchAdvertisements不发出任何advertisementreceived事件,验证超时逻辑(如setTimeout清理)是否生效 - 测试重复调用:连续两次调用扫描函数,检查是否自动取消前一次监听(如调用
abortController.abort())
注意浏览器兼容性与上下文限制
测试前必须确保运行环境满足前提条件,否则 API 根本不可用:
- 仅 Chrome / Edge(基于 Chromium)支持完整 Web Bluetooth API;Firefox 和 Safari 不支持设备扫描
- 必须运行在 HTTPS(或
localhost)下,否则navigator.bluetooth为undefined - 所有蓝牙调用必须由用户手势(如
click、tap)触发,不能在页面加载时自动执行

















