web-dev-qa-db-ja.com

Typescriptでプライベートメソッドを単体テストする方法

プライベートメソッドはクラス内でのみアクセス可能であるため、クラス内のプライベートメソッドのユニットテストを実行しようとしたときにエラーが発生しました。ここに、クラスとモカテスト用のサンプルスニペットを追加しました。プライベートメソッドの単体テストを実装するソリューションを提供してください。

クラス名:Notification.ts

class Notification {
 constructor() {}
 public validateTempalte() {
  return true;
 }

 private replacePlaceholder() {
  return true;
 }
}

単体テスト:

import {Notification} from 'Notification';
import * as chai from "chai";

describe("Notification", function(){

  describe('#validateTempalte - Validate template', function() {
      it('it should return success', function() {
        const result = new Notification()
        chai.expect(result.validateTempalte()).to.be.equal(true);
      });
    });
  describe('#replacePlaceholder - Replace Placeholder', function() {
      it('it should return success', function() {
        const result = new Notification()
        // As expected getting error "Private is only accessible within class"
        chai.expect(result.replacePlaceholder()).to.be.equal(true);
      });
    });
});

回避策として、現在、関数replacePlaceholderのアクセス指定子をpublicに変更しています。しかし、私はそれが有効なアプローチだとは思わない。

10

技術的に、TypeScriptの現在のバージョンでは、プライベートメソッドはコンパイル時にのみプライベートであることが確認されているため、呼び出すことができます。

class Example {
    public publicMethod() {
        return 'public';
    }

    private privateMethod() {
        return 'private';
    }
}

const example = new Example();

console.log(example.publicMethod()); // 'public'
console.log(example.privateMethod()); // 'private'

あなたがそれを行う方法を尋ねたので、私はこれに言及しますonly、そしてそれはあなたcouldそれを行います。

正解

ただし、そのプライベートメソッドは他のメソッドによって呼び出される必要があります...それ以外の場合はまったく呼び出されません。他のメソッドの動作をテストする場合、使用されるコンテキストでプライベートメソッドをカバーします。

プライベートメソッドを具体的にテストする場合、テストは実装の詳細に密接に結合されます(つまり、実装をリファクタリングした場合、適切なテストを変更する必要はありません)。

免責事項

まだプライベートメソッドレベルでテストする場合、コンパイラは将来の変更でmightをテストに失敗させます(つまり、コンパイラがメソッドを作成した場合 "適切に」プライベート、またはECMAScriptの将来のバージョンが可視性キーワードなどを追加した場合)。

11
Fenton

TypeScriptチェックを省略するための可能な解決策は、プロパティに動的にアクセスすることです(その良さを伝えません)。

_myClass['privateProp']_またはメソッドの場合:myClass['privateMethod']()

9
denu5