VSCode自动化测试:如何创建带有效URI的内存虚拟文档?
解决方案
你需要通过VSCode的FileSystemProviderAPI注册一个自定义内存文件系统,给虚拟文档分配带自定义协议的合法URI,全程不需要写入本地磁盘。
实现步骤
- 第一步:实现轻量内存文件系统Provider,仅需要实现测试用到的核心方法即可,文件内容直接存在内存Map中:
import * as vscode from 'vscode'; class MemoryFS implements vscode.FileSystemProvider { // 用Map存储内存中的文件内容 private files = new Map<string, Uint8Array>(); // 核心必选方法:获取文件元信息 stat(uri: vscode.Uri): vscode.FileStat { if (!this.files.has(uri.path)) { throw vscode.FileSystemError.FileNotFound(); } return { type: vscode.FileType.File, ctime: Date.now(), mtime: Date.now(), size: this.files.get(uri.path)!.length }; } // 核心必选方法:读取文件内容 readFile(uri: vscode.Uri): Uint8Array { const content = this.files.get(uri.path); if (!content) throw vscode.FileSystemError.FileNotFound(); return content; } // 核心必选方法:写入文件内容 writeFile(uri: vscode.Uri, content: Uint8Array) { this.files.set(uri.path, content); } // 测试用不到的方法可以直接抛错或空实现 createDirectory() { throw new Error('Not supported'); } readDirectory() { throw new Error('Not supported'); } delete() { this.files.clear(); } rename() { throw new Error('Not supported'); } // 必选事件监听,测试场景下空实现即可 private _emitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>(); onDidChangeFile = this._emitter.event; watch() { return { dispose() {} }; } }
- 第二步:在扩展激活逻辑中注册该文件系统,指定自定义协议(示例中用
testmem,可自行修改,不要和VSCode内置协议重名即可):
export function activate(context: vscode.ExtensionContext) { const memoryFS = new MemoryFS(); // 注册自定义协议的文件系统 context.subscriptions.push( vscode.workspace.registerFileSystemProvider('testmem', memoryFS, { isCaseSensitive: true }) ); // 后续创建虚拟文档的逻辑可以写在这里,或者封装成命令触发 }
- 第三步:生成合法URI,写入内容后打开文档即可拿到带有效URI的文档实例:
// 生成自定义协议的URI,格式为 {协议名}:///{自定义文件路径} const testUri = vscode.Uri.parse('testmem:///test-document.md'); // 写入你需要的文档内容 const content = Buffer.from('测试文档的自定义内容', 'utf8'); await memoryFS.writeFile(testUri, content); // 打开文档,此时拿到的document.uri就是合法可访问的URI const doc = await vscode.workspace.openTextDocument(testUri); // 可选:在编辑器中打开该文档 await vscode.window.showTextDocument(doc);
注意事项
- 自定义协议不要和VSCode内置协议(
file、untitled、vscode等)重名,生成的URI完全符合VSCode规范,你的扩展可以直接通过该URI访问文档。 - 测试场景下不需要做持久化,内存文件系统随扩展销毁自动释放,不会产生本地垃圾文件。
内容的提问来源于stack exchange,提问作者DarkTrick
相关产品推荐
相关产品推荐

