We have existing code that’s structured similar to following which I want to test. The challenging part here is the fact that instance of Two
is created at module root level in Three.ts
file. This makes mocks not work. I also want to use mockImplementation
inside test case because I want to manipulate the return value of runOne
from test to test.
// One.ts
export class One {
runOne() {
return "hello";
}
}
// Two.ts
import { One } from "./One";
export class Two {
private one: One = new One();
runTwo() {
console.log(this.one);
return console.log(this.one.runOne());
}
}
// Three.ts
import { Two } from "./Two";
const two: Two = new Two();
export const run = () => {
two.runTwo();
};
// main.test.ts
import { describe, Mock, test, vi } from "vitest";
import { run } from "./Three";
import { One } from "./One";
vi.mock("./One", async () => {
return {
One: vi.fn(),
};
});
describe("suite", () => {
test("test", async () => {
const MOne = One as unknown as Mock;
MOne.mockImplementation(() => {
return { runOne: () => "world" };
});
run();
});
});
Output:
spy {}
TypeError: this.one.runOne is not a function
❯ Two.runTwo __test__/Two.ts:8:33
6| runTwo() {
7| console.log(this.one);
8| return console.log(this.one.runOne());
| ^
9| }
10| }
I want to have two test scripts where runOne
returns two different values in the same test file.
describe('suite', () => {
test('first', () => {
// mock runOne to return "first"
// should print "first"
run()
})
test('second', () => {
// mock runOne to return "two"
// should print "two"
run()
})
})