如何模拟Deno内置方法,例如Deno.Command()?
模拟Deno.Command()的几种实用方法
在测试中模拟Deno对象上的Command方法,核心思路是临时替换原始的Deno.Command构造函数,让它返回你预设的结果。下面是几种常用的实现方式:
1. 用Deno标准库的mock模块处理
Deno标准库的std/testing/mock.ts提供了便捷的mock工具,适合需要快速替换并后续恢复的场景:
import { assertEquals } from "https://deno.land/std@0.208.0/assert/mod.ts"; import { mock } from "https://deno.land/std@0.208.0/testing/mock.ts"; // 待测试的业务函数:调用外部命令 async function runExternalCommand() { const cmd = new Deno.Command("echo", { args: ["hello"] }); const output = await cmd.output(); return new TextDecoder().decode(output.stdout); } Deno.test("模拟Command返回指定输出", async () => { // 先保存原始的Command构造函数,测试后要恢复 const originalCommand = Deno.Command; // 替换Deno.Command,让它返回的实例拥有预设的output方法 mock(Deno, "Command", () => ({ output: async () => ({ stdout: new TextEncoder().encode("mock output"), stderr: new Uint8Array(), success: true, code: 0, }) })); try { const result = await runExternalCommand(); assertEquals(result, "mock output"); } finally { // 必须恢复原始方法,避免影响其他测试用例 Deno.Command = originalCommand; } });
2. 直接覆盖Deno.Command(简单场景)
如果不需要复杂的mock逻辑,直接给Deno.Command赋值自定义类即可,代码更简洁:
import { assertEquals } from "https://deno.land/std@0.208.0/assert/mod.ts"; async function runExternalCommand() { const cmd = new Deno.Command("echo", { args: ["hello"] }); const output = await cmd.output(); return new TextDecoder().decode(output.stdout); } Deno.test("直接替换Command实现", async () => { const originalCommand = Deno.Command; // 自定义模拟类,实现和原始Command一致的接口 Deno.Command = class MockCommand { constructor(_cmd: string, _options: { args: string[] }) {} async output() { return { stdout: new TextEncoder().encode("direct mock result"), stderr: new Uint8Array(), success: true, code: 0, }; } } as typeof Deno.Command; try { const result = await runExternalCommand(); assertEquals(result, "direct mock result"); } finally { Deno.Command = originalCommand; } });
3. 按命令参数返回不同结果
如果需要根据不同的命令或参数返回对应模拟值,可以在mock逻辑里做判断:
import { assertEquals } from "https://deno.land/std@0.208.0/assert/mod.ts"; import { mock } from "https://deno.land/std@0.208.0/testing/mock.ts"; async function runCommand(cmd: string, args: string[]) { const command = new Deno.Command(cmd, { args }); const output = await command.output(); return new TextDecoder().decode(output.stdout); } Deno.test("根据命令参数返回对应结果", async () => { const originalCommand = Deno.Command; mock(Deno, "Command", (cmd: string, options: { args: string[] }) => ({ output: async () => { // 根据传入的命令和参数返回不同模拟值 if (cmd === "echo" && options.args[0] === "hello") { return { stdout: new TextEncoder().encode("hello from mock"), stderr: new Uint8Array(), success: true, code: 0 }; } else if (cmd === "ls") { return { stdout: new TextEncoder().encode("file1.txt\nfile2.txt"), stderr: new Uint8Array(), success: true, code: 0 }; } // 默认返回失败结果 return { stdout: new Uint8Array(), stderr: new Uint8Array(), success: false, code: 1 }; } })); try { assertEquals(await runCommand("echo", ["hello"]), "hello from mock"); assertEquals(await runCommand("ls", []), "file1.txt\nfile2.txt"); assertEquals(await runCommand("unknown", []), ""); } finally { Deno.Command = originalCommand; } });
内容的提问来源于stack exchange,提问作者hallvors
相关产品推荐
相关产品推荐

