A library for mocking Deno APIs with ease.
Warning
Alpha version. Not tested extensively or documented well yet.
- Built upon and compatible with @std/testing
- Consistent interfaces across submodules
import * as cmd from "jsr:@chiezo/amber/cmd";
Replace Deno.Command as a side effect:
cmd.mock();
assert(Deno.Command !== Original);
Stub any command by default:
cmd.mock();
await new Deno.Command("echo").output();
assertNotRun("echo");
Replace Deno.Command inside the callback:
const echo = cmd.spy("echo");
cmd.use(() => new Deno.Command("echo"));
assertSpyCalls(echo, 1);
Create a spy for a command:
const echo = cmd.spy("echo");
cmd.use(() => new Deno.Command("echo"));
assertSpyCalls(echo, 1);
Create multiple spies for different commands separately:
const echo = cmd.spy("echo");
const ls = cmd.spy("ls");
cmd.use(() => {
new Deno.Command("echo");
assertSpyCalls(echo, 1);
assertSpyCalls(ls, 0);
new Deno.Command("ls");
assertSpyCalls(echo, 1);
assertSpyCalls(ls, 1);
});
Stub a command with the default dummy:
const echo = cmd.stub("echo");
await cmd.use(() => new Deno.Command("echo").output());
assertNotRun("echo");
assertSpyCalls(echo, 1);
Stub a command with a given fake:
cmd.stub(
"echo",
class extends Deno.Command {
constructor(command: string | URL) {
super(command);
throw new Error();
}
},
);
cmd.use(() => assertThrows(() => new Deno.Command("echo")));
Restore Deno.Command:
cmd.mock();
cmd.restore();
assert(Deno.Command === Original);
Not dispose spies created:
const echo = cmd.spy("echo");
cmd.restore();
cmd.use(() => new Deno.Command("echo"));
assertSpyCalls(echo, 1);
Restore Deno.Command:
cmd.mock();
cmd.dispose();
assert(Deno.Command === Original);
Dispose spies created:
const echo = cmd.spy("echo");
cmd.dispose();
cmd.use(() => new Deno.Command("echo"));
assertSpyCalls(echo, 0);
import * as fs from "jsr:@chiezo/amber/fs";
Replace file system functions as side effects:
fs.mock();
assert(Deno.readTextFile !== original.readTextFile);
assert(Deno.readTextFileSync !== original.readTextFileSync);
Stub the current working directory by default:
fs.mock();
await fs.use(() => Deno.writeTextFile("./test.txt", "amber"));
assertRejects(() => Deno.readTextFile("./test.txt"));
Replace file system functions within the callback:
fs.use(() => {
assert(Deno.readTextFile !== original.readTextFile);
assert(Deno.readTextFileSync !== original.readTextFileSync);
});
Spy file system functions:
const spy = fs.spy(".");
await fs.use(() => Deno.readTextFile("./README.md"));
assertSpyCalls(spy.readTextFile, 1);
Spy multiple paths separately:
const cwd = fs.spy(".");
const src = fs.spy("./src");
await fs.use(() => Deno.readTextFile("./README.md"));
assertSpyCalls(cwd.readTextFile, 1);
assertSpyCalls(src.readTextFile, 0);
Accept a URL:
const spy = fs.spy(new URL("..", import.meta.url));
await fs.use(() => Deno.readTextFile("./README.md"));
assertSpyCalls(spy.readTextFile, 1);
Not write to the original path:
const stub = fs.stub("./test.txt");
await fs.use(() => Deno.writeTextFile("./test.txt", "amber"));
assertEquals(
(await Deno.permissions.query({ name: "write", path: "./test.txt" }))
.state,
"prompt",
);
assertSpyCalls(stub.writeTextFile, 1);
Make the original file readable initially (readThrough):
const stub = fs.stub(".");
await fs.use(() => Deno.readTextFile("./README.md"));
assertSpyCalls(stub.readTextFile, 1);
Make the updated content readable after being written:
fs.stub(".");
await fs.use(async () => {
await Deno.writeTextFile("./README.md", "amber");
assertEquals(
await Deno.readTextFile("./README.md"),
"amber",
);
});
Throw on a file that has not been written if readThrough is disabled:
fs.stub(".", { readThrough: false });
fs.use(() => assertThrows(() => Deno.readTextFileSync("./README.md")));
Stub multiple paths separately:
const cwd = fs.stub(".");
const src = fs.stub("./src");
await fs.use(() => Deno.readTextFile("./README.md"));
assertSpyCalls(cwd.readTextFile, 1);
assertSpyCalls(src.readTextFile, 0);
Restore file system functions:
fs.mock();
fs.restore();
assert(Deno.readTextFile === original.readTextFile);
assert(Deno.readTextFileSync === original.readTextFileSync);
Not dispose spies created:
const spy = fs.spy(".");
fs.restore();
await fs.use(() => Deno.readTextFile("./README.md"));
assertSpyCalls(spy.readTextFile, 1);
Restore file system functions:
fs.mock();
fs.dispose();
assert(Deno.readTextFile === original.readTextFile);
assert(Deno.readTextFileSync === original.readTextFileSync);
Dispose spies created:
const spy = fs.spy(".");
fs.dispose();
await fs.use(() => Deno.readTextFile("./README.md"));
assertSpyCalls(spy.readTextFile, 0);
import { all } from "jsr:@chiezo/amber/util";
Mock multiple modules simultaneously:
const echo = cmd.stub("echo");
const root = fs.stub("../");
all(cmd, fs).mock();
new Deno.Command("echo");
assertSpyCalls(echo, 1);
await Deno.readTextFile("../README.md");
assertSpyCalls(root.readTextFile, 1);
Use multiple modules simultaneously:
const echo = cmd.stub("echo");
const root = fs.stub("../");
await all(cmd, fs).use(async () => {
new Deno.Command("echo");
assertSpyCalls(echo, 1);
await Deno.writeTextFile("../test.txt", "amber");
assertSpyCalls(root.writeTextFile, 1);
assertEquals(
await Deno.readTextFile("../test.txt"),
"amber",
);
assertSpyCalls(root.readTextFile, 1);
});
Restore multiple modules simultaneously:
all(cmd, fs).mock();
all(cmd, fs).restore();
assert(Deno.Command === original.Command);
assert(Deno.readTextFile === original.readTextFile);
Dispose multiple modules simultaneously:
const echo = cmd.spy("echo");
const root = fs.spy("../");
all(cmd, fs).mock();
all(cmd, fs).dispose();
new Deno.Command("echo");
assertSpyCalls(echo, 0);
await Deno.readTextFile("../README.md");
assertSpyCalls(root.readTextFile, 0);