Mocking TypeScript class with Vitest

  Kiến thức lập trình

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?

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT