I am encountering a situation where I have a class A
that imports another class B
from a separate module and creates an instance of it. While writing tests for class A
, I want to stub or mock some of the methods of class B
.
Below is an example code snippet:
// 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');
})
In situations like this, I understand that using constructor injection could be a viable alternative to mocking the module, but there are instances where that may not be feasible.