web-dev-qa-db-ja.com

jestでTypeScriptインターフェイスをモックする

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);
    });
});

私はこれをさまざまな方法で満たすためにモックオブジェクトを作成しようとしましたが、どれも機能しません。たとえば、このモックを割り当てる:

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

以下のラインに沿って何かを生成します:

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

モックはインターフェースと同じshapeを持つ必要があります。

docs から:TypeScriptのコア原則の1つは、値が持つ形状に焦点を合わせたタイプチェックです。これは「ダックタイピング」または「構造」と呼ばれることもありますサブタイプ」。

そう mathlib.multiplierは、IMultiplierに準拠するオブジェクトに割り当てる必要があります。

例のIMultiplierは次のように見えると思います。

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

したがって、サンプルのテストは、問題の行を次のように変更することで正常に機能します。

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