I writing some unit tests in Vitest framework for my app with typescript and React, but I came across a problem with mocking a static methods.
Here is my code:
export class Person {
private age: number;
constructor(public name: string) {
this.age = 20;
}
public getAge() {
return this.age;
}
}
export class StaticPerson {
public static getAge() {
return 20;
}
}
import { Person, StaticPerson } from "./person";
export class Interviewer {
public askAge(): number {
const person = new Person("John");
return person.getAge();
}
public askStaticAge(): number {
return StaticPerson.getAge();
}
}
Unit tests:
import { describe, it, expect, vi } from "vitest";
import { Interviewer } from "./interviewer";
//this test will pass
describe("interviewer", () => {
it("return mocked age", () => {
vi.mock("./person", () => {
const Person = vi.fn(() => ({
getAge: vi.fn(() => 15),
}));
return { Person };
});
const interviewer = new Interviewer();
const age: number = interviewer.askAge();
expect(age).toBe(15);
});
});
//this test fails
it("return mocked age from static method", () => {
vi.mock("./person", () => {
const StaticPerson = vi.fn(() => ({
getAge: vi.fn(() => 15),
}));
return { StaticPerson };
});
const interviewer = new Interviewer();
const age: number = interviewer.askStaticAge();
expect(age).toBe(15);
});
First test, where I calling non-static method is passing just fine, but second test with calling static getAge throwing an error:
TypeError: StaticPerson.getAge is not a function
FAIL src/interviewer.test.tsx > return mocked age from static method TypeError: StaticPerson.getAge is not a function ❯ Interviewer.askStaticAge src/interviewer.tsx:10:25 8| 9| public askStaticAge(): number { 10| return StaticPerson.getAge(); | ^ 11| } 12| } ❯ src/interviewer.test.tsx:29:35
I cannot find any mention of mocking static methods in documentation, or any example how to mock that.
Instead of adding it on the prototype chain you could do the following.
import { describe, expect, it, vi } from 'vitest';
import { Interviewer } from './interview';
vi.mock('./person', () => {
const Person = vi.fn();
Person.prototype.getAge = vi.fn(() => 15);
const StaticPerson = vi.fn();
StaticPerson['getAge'] = vi.fn(() => 15);
return { Person, StaticPerson };
});
//this test will pass
describe('interviewer', () => {
it('return mocked age', () => {
const interviewer = new Interviewer();
const age: number = interviewer.askAge();
expect(age).toEqual(15);
});
});
//this test now passes
it('return mocked age from static method', () => {
const interviewer = new Interviewer();
const age: number = interviewer.askStaticAge();
expect(age).toEqual(15);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With