Sinon: プライベートメンバーを持つクラスでStubInstanceを作成できません

作成日 2019年01月04日  ·  3コメント  ·  ソース: sinonjs/sinon

バグを説明する
Xが少なくとも1つのプライベートメンバーを持つクラスであるsinon.createStubInstance(X)の場合、次のようなエラーが発生します。

タイプ 'SinonStubbedInstanceの引数'タイプ' Foo 'のパラメータに割り当てることはできません。
プロパティ '_private'がタイプ 'SinonStubbedInstanceにありません'ただし、タイプ' Foo 'では必須です。

describe('SinonTest', () => {
  class Foo {
    public talk() {
      return 'hi';
    }
    private _private() {
      return null;
    }
  }

  function printSpeech(foo: Foo) {
    console.log(foo.talk());
  }
  it('should allow you to pass a stub as a the original', () => {
    const mockFoo = sinon.createStubInstance(Foo);

    printSpeech(mockFoo);
  });
});

再現するには
動作を再現する手順:

  1. モカとシノンでプロジェクトを立ち上げます。
  2. 単体テスト仕様ファイルを作成する
  3. 上記のコードスニペットを貼り付けて、必要なインポートを追加します
  4. printSpeech(mockFoo)の行のエラーを参照してください

予想される行動
私はこれがエラーなしで機能することを期待します。 _private()については気にせず、その動作を直接テストするつもりもありませんが、ビルド時エラーが発生することはありません。 Jasmineの実装には他の欠陥がありますが、Jasmineはjasmine.createSpyObjでこのケースをサポートしています。

コンテキスト(次の情報を入力してください):

  • ライブラリバージョン:sinon:7.2.2、@ types / sinon:7.0.3
  • 環境:WSL Ubuntu 16.04、ノード10

  • 使用している他のライブラリ:Mocha 5.2.0

編集:ここにstackblitzがありますhttps://stackblitz.com/edit/typescript-nfbgno?file=index.ts

process.stdoutはブラウザで実行されているため文句を言いますが、実際の問題はコンパイル時であるため、これは重要ではありません。

最も参考になるコメント

これは決定的な解決策ではありませんが、次の関数でこの問題を修正することができました。

import { createStubInstance, StubbableType, SinonStubbedInstance, SinonStubbedMember } from 'sinon';

export type StubbedClass<T> = SinonStubbedInstance<T> & T;

export function createSinonStubInstance<T>(
  constructor: StubbableType<T>,
  overrides?: { [K in keyof T]?: SinonStubbedMember<T[K]> },
): StubbedClass<T> {
  const stub = createStubInstance<T>(constructor, overrides);
  return stub as unknown as StubbedClass<T>;
}

明らかに、これはプライベートメソッドを実装していないため、それらを呼び出すことはできません(設計上はそうすべきではありません)。 このラッパー関数を使用すると、クラス内のすべてのパブリック関数/メンバー、およびsinonのスタブヘルパー関数とStubbedClassのコード補完を取得できます。テストでTとして使用される有効なタイプです。

全てのコメント3件

これはTypescriptの問題です。 Typescriptを明示的にサポートしていないため、これを調べるのに時間をかけるつもりはありません。 Typescriptがどういうわけかプライベートメンバーをサポートしていることは、その型システムのプロパティであり、さまざまな方法で実装できます。 Typescriptを使用したとき、Typescriptの遊び場に行き、出力を調べて何が行われたかを理解することで、このような問題を解決することがよくありました。 それはあなたがする必要があることでもあります。

これは決定的な解決策ではありませんが、次の関数でこの問題を修正することができました。

import { createStubInstance, StubbableType, SinonStubbedInstance, SinonStubbedMember } from 'sinon';

export type StubbedClass<T> = SinonStubbedInstance<T> & T;

export function createSinonStubInstance<T>(
  constructor: StubbableType<T>,
  overrides?: { [K in keyof T]?: SinonStubbedMember<T[K]> },
): StubbedClass<T> {
  const stub = createStubInstance<T>(constructor, overrides);
  return stub as unknown as StubbedClass<T>;
}

明らかに、これはプライベートメソッドを実装していないため、それらを呼び出すことはできません(設計上はそうすべきではありません)。 このラッパー関数を使用すると、クラス内のすべてのパブリック関数/メンバー、およびsinonのスタブヘルパー関数とStubbedClassのコード補完を取得できます。テストでTとして使用される有効なタイプです。

@pauloavelarの回答はまだ推奨される回避策ですか?

このページは役に立ちましたか?
0 / 5 - 0 評価