Jess182
Jess1824mo ago

Incorrect documentation example (partial mocking)

Hi, I'm trying to replicate the example in the partial mocking documentation, but the test fails because it doesn't override the implementation. VSCode also detects that the spy() function should only receive two arguments. How can i fix or do partial mocking? Thanks - jsr:@std/testing/mock 1.0.12 - deno 2.3.1 - linux mint 22.1 ref: https://docs.deno.com/examples/mocking_tutorial/#partial-mocking
Deno
Testing in isolation with mocks
Master the art of mocking in your unit tests. Learn how spies, stubs, fake time, and other Deno tools let you improve your code and confidence
No description
6 Replies
Jess182
Jess182OP4mo ago
I'm still stuck, do you know how I could do partial mocking?
kt3k
kt3k3mo ago
Sorry for the confusion. The above example looks wrong to me. If you need to replace the implementation of method, you need to use stub function from @std/testing/mock:
import { assertEquals } from "jsr:@std/assert";
import { assertSpyCall, assertSpyCalls, stub } from "jsr:@std/testing/mock";

class UserService {
async getUser(id: string) {
// Complex database query
return { id, name: "Database User" };
}

async formatUser(user: { id: string; name: string }) {
return {
...user,
displayName: user.name.toUpperCase(),
};
}

async getUserFormatted(id: string) {
const user = await this.getUser(id);
return this.formatUser(user);
}
}

Deno.test("partial mocking with spies", async () => {
const service = new UserService();

// Only mock the getUser method
const getUserSpy = stub(
service,
"getUser",
() => Promise.resolve({ id: "test-id", name: "Mocked User" }),
);

try {
// The formatUser method will still use the real implementation
const result = await service.getUserFormatted("test-id");

assertEquals(result, {
id: "test-id",
name: "Mocked User",
displayName: "MOCKED USER",
});

// Verify getUser was called with the right arguments
assertSpyCalls(getUserSpy, 1);
assertSpyCall(getUserSpy, 0, {
args: ["test-id"],
});
} finally {
getUserSpy.restore();
}
});
import { assertEquals } from "jsr:@std/assert";
import { assertSpyCall, assertSpyCalls, stub } from "jsr:@std/testing/mock";

class UserService {
async getUser(id: string) {
// Complex database query
return { id, name: "Database User" };
}

async formatUser(user: { id: string; name: string }) {
return {
...user,
displayName: user.name.toUpperCase(),
};
}

async getUserFormatted(id: string) {
const user = await this.getUser(id);
return this.formatUser(user);
}
}

Deno.test("partial mocking with spies", async () => {
const service = new UserService();

// Only mock the getUser method
const getUserSpy = stub(
service,
"getUser",
() => Promise.resolve({ id: "test-id", name: "Mocked User" }),
);

try {
// The formatUser method will still use the real implementation
const result = await service.getUserFormatted("test-id");

assertEquals(result, {
id: "test-id",
name: "Mocked User",
displayName: "MOCKED USER",
});

// Verify getUser was called with the right arguments
assertSpyCalls(getUserSpy, 1);
assertSpyCall(getUserSpy, 0, {
args: ["test-id"],
});
} finally {
getUserSpy.restore();
}
});
kt3k
kt3k3mo ago
See also the docs in JSR https://jsr.io/@std/testing/doc/mock
JSR
mock - @std/testing - JSR
@std/testing on JSR: Tools for testing Deno code like snapshot testing, bdd testing, and time mocking
kt3k
kt3k3mo ago
I'm trying to fix the docs above https://github.com/denoland/docs/pull/1766
GitHub
fix some mock tutorial examples by kt3k · Pull Request #1766 · de...
This PR fixes 2 examples in examples/mocking_tutorial page.
Jess182
Jess182OP3mo ago
Thanks @kt3k for the clarification, is there any plan for the 'spy()' function to replace the implementations?
KyleJune
KyleJune3mo ago
Spy is just for observing without replacing the original. Stub is for observing and replacing the original. Stub is an extension of Spy. All the assertSpy functions work with stubs. If spy could replace the original function there would be no difference between spy and stub.

Did you find this page helpful?