I designed a custom class in TypeScript that contains a method:
// @/utils/llm.ts
export default class LLMUtils {
...
async discussWithLLM(
history: ChatHistory,
question: string,
): Promise<{ answer: MessageContent; sources: DocumentWithScore[] }> {
...
}
...
}
I’ve been using Vitest for testing & mocking purposes, but I’m facing a weird behavior.
I have two different tests where I’ve been mocking the output of this discussWithLLM
method:
// test 1:
const llmMock = await import('@/utils/llm.ts');
vi.mocked(llmMock.default).mockImplementation(() => ({
discussWithLLM: vi.fn().mockResolvedValue({
answer: 'Some answer without sources',
sources: [],
}),
}));
// test 2:
const llmMock = await import('@/utils/llm.ts');
vi.mocked(llmMock.default).mockImplementation(() => ({
discussWithLLM: vi.fn().mockResolvedValue({
answer: 'Some answer with sources',
sources: [{
document: {
metadata: {
source: 'source1',
loc: {
pageNumber: 1
},
},
},
},
{
document: {
metadata: {
source: 'source2',
loc: {
pageNumber: 2
},
},
},
},
],
}),
}));
When running test 1 or 2 individually, the mocking works as expected in both cases. When running the entire test suite (so only these 2 tests), test 2’s mocks leak into test 1’s.
I’ve implemented a beforeEach
hook that mocks the original LLMUtils
class, and an afterEach
hook that clears the mocks and resets modules:
beforeEach(() => {
// ...
vi.mock('@/utils/llm.js', () => ({
default: vi.fn().mockImplementation(() => ({
discussWithLLM: vi.fn(),
})),
}));
// ...
})
afterEach(() => {
vi.clearAllMocks();
vi.resetModules();
});
What’s causing this side effect?