如何使用 vitest 模拟 TypeScript 类

问题描述 投票:0回答:1

我有一个类

A
,它从不同的模块导入类
B
并实例化它。在我对
A
类的测试中,我想存根/模拟
B
类的一些方法。

一些示例代码:

// Formatter.ts
export class Formatter {
   format(msg: string): string {
     return `--- [INFO] ${msg}\n`;
   }
}

// FormattedStore.ts
import {Formatter} from '@/Formatter'
export class FormattedStore implements Store {
   public store: string[];
   construct() {
     this.formatter = new Formatter();
     this.store = [];
   }

   write(msg: string): void {
      this.store.push(this.formatter.format(msg));
   }
}

// FormattedStore.spec.ts
import {FormattedStore} from '@/FormattedStore';
import {Formatter} from '@/Formatter'
import {vi, expect, test} from 'vitest';

vi.mock( '@/Formatter', () => ({ 
 Formatter: vi.fn() // What's the correct and type-safe way to mock this?
}));

test('it stores formatted message', () => {
   //  How do I mock the formatter here with the return 'formatted test message'?
   const store = new FormattedStore();
   store.write('TestMessage');

   expect(store.store[0]).toBe('formatted test message');
})

我知道我可以使用构造函数注入而不是模拟模块,但我有一个情况是不可能的。

typescript mocking vitest
1个回答
0
投票

vitest-mock-extend 解决了这个问题:

// FormattedStore.spec.ts
import {mock} from 'vitest-mock-extended';
import {FormattedStore} from '@/FormattedStore';
import {Formatter} from '@/Formatter'
import {vi, expect, test} from 'vitest';

vi.mock( '@/Formatter', () => ({ 
 Formatter: mock<Formatter>()
}));

test('it stores formatted message', () => {
   Formatter.format.mockReturnValue('formatted test message');
   const store = new FormattedStore();
   store.write('TestMessage');

   expect(store.store[0]).toBe('formatted test message');
})
© www.soinside.com 2019 - 2024. All rights reserved.