无法在 Vitest 中模拟静态方法 - 错误“不是函数”

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

我使用 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 

我在文档中找不到任何关于模拟静态方法的提及,也找不到任何如何模拟它的示例。

typescript unit-testing static mocking vitest
1个回答
0
投票

您可以执行以下操作,而不是将其添加到原型链上。

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);
});
© www.soinside.com 2019 - 2024. All rights reserved.