[解決済み】Angular / TypeScriptのプライベートメソッドのユニットテストをJasmineで記述する方法
質問
Angular 2でプライベート関数をテストするにはどうしたらいいですか?
class FooBar {
private _status: number;
constructor( private foo : Bar ) {
this.initFooBar();
}
private initFooBar(){
this.foo.bar( "data" );
this._status = this.fooo.foo();
}
public get status(){
return this._status;
}
}
私が見つけた解決策
-
クロージャの中にテストコードそのものを入れるか、クロージャの中に、外部スコープの既存のオブジェクトのローカル変数への参照を格納するコードを追加する。
後でツールを使ってテストコードを取り除く。 http://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/
この問題を解決するための良い方法があれば教えてください。
P.S
-
このような類似の質問に対する回答のほとんどは、問題に対する解決策を与えていないため、この質問をさせていただきました。
-
ほとんどの開発者は、プライベート関数をテストしてはいけないと言いますが、私はそれが間違っているとも正しいとも言いませんが、私の場合、プライベート関数をテストする必要性があるのです。
どのように解決するのですか?
公開APIだけをユニットテストするのは良い目標ですが、そう簡単ではないようで、APIとユニットテストのどちらかを妥協することになると感じることがありますね。このことは、まさにあなたが求めていることなので、もうわかっていると思いますが、ここでは触れません :)
TypeScriptでは、ユニットテストのためにプライベートメンバーにアクセスする方法をいくつか発見した。このクラスについて考えてみましょう。
class MyThing {
private _name:string;
private _count:number;
constructor() {
this.init("Test", 123);
}
private init(name:string, count:number){
this._name = name;
this._count = count;
}
public get name(){ return this._name; }
public get count(){ return this._count; }
}
TSがクラスメンバへのアクセスを
private
,
protected
,
public
というのも、JSにはプライベート・メンバが存在しないのです。これは純粋にTSコンパイラのために使われているのです。そのため
-
にアサートすることができます。
any
で、コンパイラがアクセス制限について警告するのを回避することができます。(thing as any)._name = "Unit Test"; (thing as any)._count = 123; (thing as any).init("Unit Test", 123);
この方法の問題点は、コンパイラが、あなたが
any
そのため、望ましい型エラーは発生しません。(thing as any)._name = 123; // wrong, but no error (thing as any)._count = "Unit Test"; // wrong, but no error (thing as any).init(0, "123"); // wrong, but no error
これでは、リファクタリングが難しくなるのは明らかです。
-
配列アクセスを使用することができます (
[]
) を使って、プライベートメンバーを取得することができます。thing["_name"] = "Unit Test"; thing["_count"] = 123; thing["init"]("Unit Test", 123);
見た目は変ですが、TSC は実際には型に直接アクセスしたかのように検証します。
thing["_name"] = 123; // type error thing["_count"] = "Unit Test"; // type error thing["init"](0, "123"); // argument error
正直なところ、なぜこれがうまくいくのかわかりません。 これはどうやら 意図的な "escape hatch" を使えば、型安全性を失うことなくプライベートメンバーにアクセスすることができます。これはまさに、ユニットテストに必要なことだと思います。
以下は TypeScript Playground での動作例 .
TypeScript 2.6に対応した編集
もう一つの方法として
// @ts-ignore
(
TS 2.6で追加された
を使用すると、次の行のすべてのエラーを単純に抑制することができます。
// @ts-ignore
thing._name = "Unit Test";
これの問題は、まあ、次の行のすべてのエラーを抑制してしまうことです。
// @ts-ignore
thing._name(123).this.should.NOT.beAllowed("but it is") = window / {};
個人的には
@ts-ignore
はコード臭であり、docsの言うとおりです。
このコメントを使用することをお勧めします。 を惜しまない . [原文のまま強調].
関連
-
[解決済み】VSCodeはモジュール'@angular/core'や他のモジュールを見つけることができません。
-
[解決済み】Angularで実際のエラーメッセージの代わりに「Http failure response for (unknown url): 0 Unknown Error」が表示されるのですが。
-
[解決済み】「ルーター・アウトレット」は既知の要素ではない
-
[解決済み] チョキダーからのエラー(C:┣ᴗ┣)。Error: EBUSY: resource busy or locked, lstat 'C:\DumpStack.log.tmp.
-
[解決済み] Angular2 Final Release - 「Error: AngularにはZone.jsのプロリフィルが必要です"
-
[解決済み] プライベートメソッド、フィールド、インナークラスを持つクラスをテストするにはどうすればよいですか?
-
[解決済み] Mockitoでvoidメソッドをモックする方法
-
[解決済み] Jasmineで'Error'が投げられることを期待するテストを書くには、どうすればよいですか?
-
[解決済み] プライベートメソッドのユニットテストはどのように行うのですか?
-
[解決済み] ファイルシステムに依存するコードの単体テスト
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Angular 6 エラー表示から 'mat-form-field' は既知の要素ではありません。
-
[解決済み] Angular 4: コンポーネントファクトリが見つかりません。@NgModule.entryComponents に追加しましたか?
-
[解決済み] Angular material Angular Material コアテーマが見つかりませんでした。
-
[解決済み] 未定義のプロパティ 'filter' を読み取ることができません。
-
[解決済み] webpack のアップグレード後、名前空間 NodeJS が見つからない
-
[解決済み] Angular 2でディレイを作成する方法
-
[解決済み] Angular 6 Error trying to diff '[object Object]'. 配列と反復記号のみが許可されます。
-
[解決済み] Angular2 Selectorが、ネストしたComponentのどの要素にもマッチしない。
-
[解決済み] Angular2において、テンプレートを必要としないコンポーネントがありますが、テンプレートエラーが発生します。
-
[解決済み] Angularアプリのシンタックスエラー。予期しないトークン <