我使用 TypeScript 和 React 在 Vitest 框架中为我的应用程序编写了一些单元测试,但是我遇到了模拟静态方法的问题。
这是我的代码:
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();
}
}
单元测试:
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);
});
第一个测试,我调用非静态方法通过得很好,但第二个测试调用静态 getAge 抛出错误:
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
我在文档中找不到任何关于模拟静态方法的提及,也找不到任何如何模拟它的示例。
您可以执行以下操作,而不是将其添加到原型链上。
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);
});