申し訳ありませんので、私は長い間、問題を抱えており、残りのコミュニティからの意見を聞きたいと思います。AngularJsでプライベートメソッドを使ってテスト可能なコントローラを書く方法は?
まず、いくつかの抽象的なコントローラを見てみましょう。
function Ctrl($scope, anyService) {
$scope.field = "field";
$scope.whenClicked = function() {
util();
};
function util() {
anyService.doSmth();
}
}
明らかに私たちはここにある:
$scope
とコントローラのための定期的な足場
- をしてスコープに取り付けたいくつかのサービスが
- を注入し、いくつかのフィールドと機能
util()
今、このクラスをユニットテストでカバーしたいと思います(Jasmi ne)。しかし、問題は、私がutil()
メソッドが呼び出されるいくつかのアイテムを(コールwhenClicked()
)クリックすると確認したいということです。ジャスミンテストでは、util()
のモックが定義されていないか、呼び出されていないというエラーが常に出ているので、私はその方法を知らない。
注:私はこの特定の例を修正しようとしていません。このようなコードパターンを一般的にテストすることを求めています。ですから、「正確なエラーは何ですか?」と教えてください。私はそれをどうやって解決するかではなく、どうやって行うのかを尋ねています。
私はこれを回避いくつかの方法を試してきた:
- を、私は、この関数は、このオブジェクトに添付されていないと明らかに私は私のユニットテストで
$scope
を使用することはできません(それは通常のメッセージExpected spy but got undefined
で終わります又は)同様の - Iは
Ctrl.util = util;
介してコントローラオブジェクトにそれらの機能を結合した後Ctrl.util = jasmine.createSpy()
ようモックを検証するが、この場合にCtrl.util
をテスト私はを変更しよう - 失敗ように呼び出されていない試みが
this
オブジェクトに添付し、運
まあで、再びCtrl.util
をあざけることを、私はこの周りに自分の道を見つけることができない、私はJS忍者からいくつかの助けを期待し、作業フィドルは完璧になります。
明確にするためには、あなたが持っているカプセル化されたロジックを挿入する必要があり、コントローラーは**これらの注入された論理アクターをテンプレートへの配信のためにスコープ変数で組み立てる責任しか負いません。 – MikeMac
良いとは言えますが、テストしたいことは、if($ scope.flag)service.a();という単純なものです。 else service.b(); '。これだけのコンポーネントを抽出するのは自然ではありません。しかし、私はあなたの意見を得て、結局のところ、これは有効なアプローチだと思います。 –
@ŁukaszBachmanプライベートメソッドに抽出したコードが単なる単純なもので、別の模擬可能なサービスに抽出できない場合は、 'Ctrl'の内部コード分割を無視して、このロジックを直接確認してみませんか?すなわち、あなたの例では、 'util()'の呼び出しを検証する代わりに、 'anyService.doSmth()'(そして 'util()'にあるかもしれない他のサービス呼び出し)を検証します。 –