3

Angular (そして実を言うと JS 自体) を初めて使用する私は、サービスとディレクティブの個別の単体テストに苦労しています。インターネットで見つかったさまざまな例からソリューションをコンパイルしようとしましたが、失敗しました。

私はサービスを持っています:

angular.module('myApp.services', [])
.factory('autoCmpltDataSvc', function ($http) {
    return {
        source: function (request, response) {
            $http({
                method: 'jsonp',
                url: 'http://ws.geonames.org/searchJSON?callback=JSON_CALLBACK',
                params: {
                    featureClass: "P",
                    style: "full",
                    maxRows: 12,
                    name_startsWith: request.term
                }
            }).success(function (data, status) {
                response($.map(data.geonames, function (item) {
                    return {
                        label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
                        value: item.name,
                        geonameId: item.geonameId
                    }
                }));
            });
        }
    }
});

事前定義された配列を渡す実際の Web サービスとのやり取りを偽造し、request.term に異なる値を渡したときに正しい応答が返されることを確認したいと思います。

もう 1 つのタスクは、ディレクティブの単体テストです (jquery オートコンプリートのラッパー)。

angular.module('myApp.directives', [])
.directive('autocomplete', function (autoCmpltDataSvc) {
      return {
          restrict: 'E',
          replace: true,
          transclude: true,
          template: '<input id="DstnSlctr" ng-model="autocomplete" type="text"/>',
          link: function (scope, element, attrs) {
              scope.$watch(autoCmpltDataSvc, function () {
                  element.autocomplete({
                      source: autoCmpltDataSvc.source,
                      select: function (event, ui) {
                          scope[attrs.selection] = ui.item.value;
                          scope[attrs.selectionid] = ui.item.geonameId;
                          scope.$apply();
                      }
                  });
              });
          }
      }
  });

定義済みの配列を使用してサービスの呼び出しを偽造し、スコープが正しく変更されていることを確認したいと思います。

それらを個別にテストすることは可能ですか、それともこのタスクには e2e テストのみを使用する必要がありますか?

返信ありがとうございます!クセニア

4

1 に答える 1

2

このサービスでは、基本的に、単体テストで $httpBackend を使用する必要があります。angular が行うことは、($http の背後で) 使用する $httpBackend を持っていることです。しかし、それを単体テストに注入すると、魔法のように呼び出しを認識してインターセプトします。

docごとに、実行する必要があるのは、実際の URL (および単体テストで渡すパラメーター) を beforeEach に提供し、afterEach を追加して、http 要求をステージングすることです。注: ドキュメントにタイプミスがあると思います

var $http; //  and should probably be: var $httpBackend

ディレクティブの場合は異なります。ディレクティブ全体を作成した場合、単体テストはおそらくはるかに簡単な方法です。プラグインをラップするときは、いくつかのことを考慮する必要があります。まず、e2e テストを作成することが最初のステップとして適切です。次に、(ディレクティブ内の) 独自のコードをヘルパー メソッドに入れることができ、その部分が単体テスト可能かどうかを確認します。

于 2012-11-22T21:07:00.483 に答える