可以用jest模拟typescript接口吗?

例如:

import { IMultiplier } from "./IMultiplier";

export class Math {
  multiplier: IMultiplier;

  public multiply (a: number, b: number) {
    return this.multiplier.multiply(a, b);
  }
}

然后在测试中:

import { Math } from "../src/Math";
import { IMultiplier } from "../src/IMultiplier";

describe("Math", () => {

    it("can multiply", () => {
        let mathlib = new Math();
        mathlib.multiplier = // <--- assign this property a mock
        let result = mathlib.multiply(10, 2);
        expect(result).toEqual(20);
    });
});

我已经try 过创建一个模拟对象来满足这一要求,但没有一种方法有效.例如,将其分配给此模拟:

let multiplierMock = jest.fn(() => ({ multiply: jest.fn() }));

将产生以下内容:

Error - Type 'Mock<{ multiply: Mock<{}>; }>' is not assignable to type 'IMultiplier'.

推荐答案

模拟只需要与接口具有相同的shape.

(从docs:One of TypeScript’s core principles is that type-checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”.开始)

所以mathlib.multiplier只需要分配给一个符合IMultiplier的对象.

我猜示例中的IMultiplier看起来像这样:

interface IMultiplier {
  multiply(a: number, b: number): number
}

因此,通过将相关行更改为以下内容,示例测试将很好地工作:

mathlib.multiplier = {
  multiply: jest.fn((a, b) => a * b)
};

Typescript相关问答推荐

TypScript ' NoInfer '类型未按预期工作

带有联合参数的静态大小数组

如果在TypeScript中一个原始的类方法是递归的,如何使用类decorator 模式?

使用`renderToPipeableStream`时如何正确恢复服务器端Apollo缓存?

为什么我的Set-Cookie在我执行下一次请求后被擦除

为什么我的一个合成函数不能推断类型?

使用Dockerfile运行Vite React应用程序时访问env变量

Cypress页面对象模型模式.扩展Elements属性

Angular文件上传到Spring Boot失败,多部分边界拒绝

从对象类型描述生成类型

如何在typescript中为this关键字设置上下文

有没有可能创建一种类型,强制在TypeScrip中返回`tyPeof`语句?

为什么TypeScrip不能解析对象析构中的赋值?

Typescript -返回接口中函数的类型

17个Angular 的延迟观察.如何在模板中转义@符号?

如何通过属性名在两个泛型数组中找到匹配的对象?

如何从上传文件中删除预览文件图标?

类型判断数组或对象的isEmpty

仅当定义了值时才按值筛选数组

TypeScript 中的通用函数包装和类型推断