57

さて、私は長い間いくつかの問題に出くわしてきました。他のコミュニティからの意見を聞きたいと思います.

まず、いくつかの抽象コントローラーを見てみましょう。

function Ctrl($scope, anyService) {

   $scope.field = "field";
   $scope.whenClicked = function() {
      util();
   };

   function util() {
      anyService.doSmth();
   }

}

明らかに、ここにあります:

  • $scope一部のサービスが注入されたコントローラーの通常の足場
  • スコープにアタッチされたいくつかのフィールドと関数
  • プライベートメソッドutil()

ここで、このクラスを単体テスト (Jasmine) でカバーしたいと思います。ただし、問題は、メソッドが呼び出されるwhenClicked()アイテムをクリック (call ) したときに確認したいことです。ジャスミンのテストでは、モックが定義されていないutil()か、呼び出されていないというエラーが常に発生するため、その方法がわかりません。util()

注: この特定の例を修正しようとしているわけではなく、一般的なコード パターンのテストについて質問しています。ですから、「正確なエラーとは」とは言わないでください。これを修正する方法ではなく、それを行う方法を尋ねています。

私はこれを回避する方法をいくつか試してきました:

  • $scopeこの関数がこのオブジェクトに関連付けられていないため、ユニットテストで使用できないことは明らかです(通常、メッセージExpected spy but got undefinedなどで終了します) 。
  • これらの関数をコントローラーオブジェクトにアタッチしてから、Ctrl.util = util;モックを検証しようとしCtrl.util = jasmine.createSpy()ましたが、この場合Ctrl.utilは呼び出されていないため、テストは失敗します
  • util()オブジェクトにアタッチして再びthis嘲笑するように変更しようとしましたが、うまくいきませんでしたCtrl.util

まあ、私はこれを回避する方法を見つけることができません.JS忍者からの助けを期待しています.動作するフィドルは完璧です.

4

4 に答える 4

7

私は別のアプローチでチャイムを鳴らすつもりです。プライベート メソッドをテストするべきではありません。そのため、それらは非公開です。これは、使用法とは関係のない実装の詳細です。

たとえば、util がいくつかの場所で使用されていたにもかかわらず、他のコードのリファクタリングに基づいて、この 1 つの場所でのみ呼び出されていることに気付いた場合はどうなるでしょうか。余分な関数呼び出しがあるのはなぜですか? 上記の提案を使用して、呼び出されたものをテストしてanyService.doSmith()いる$scope.whenClicked()と仮定するutil()と、プログラムの機能を変更していなくても、テストは壊れます。単体テストの主な価値の 1 つは、何かを壊すことなくリファクタリングを簡素化することです。

あなたがする必要があるのは、呼び出されたときに$scope.whenClickedanyService.doSmth()呼び出されるようにすることです。あなただけが必要です:

spyOn(anyService,'doSmith')
scope.whenClicked();
expect(anyService.doSmith).toHaveBeenCalled();
于 2015-05-13T08:41:30.620 に答える