【问题标题】:Unit-testing Angular services and directives单元测试 Angular 服务和指令
【发布时间】:2012-11-10 20:35:34
【问题描述】:

作为 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 值时是否返回正确的响应。

另一个任务是对指令进行单元测试(围绕 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 测试来完成这项任务?

提前感谢您的回复! 克塞尼亚

【问题讨论】:

    标签: unit-testing service autocomplete angularjs directive


    【解决方案1】:

    对于服务,基本上您要做的就是在单元测试中使用 $httpBackend。 Angular 的作用是它使用了一个 $httpBackend(在 $http 后面)。但是当你将它注入到单元测试中时,它会神奇地知道并拦截调用。

    根据doc,您需要做的是通过在 beforeEach 中提供真实的 url(以及您将在单元测试中传递的参数)来暂存您的 http 请求,并添加一个 afterEach。注意:我认为 doc 有错字

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

    对于指令,这取决于。如果您已经创建了整个指令,那么单元测试可能是一条更容易的道路。在包装插件时,您可能会考虑几件事。首先,编写 e2e 测试可能是很好的第一步。其次,看看您自己的代码(在指令中)是否可以放入辅助方法中,并且该部分可能是可单元测试的。

    【讨论】:

    • 谢谢!我已经重构了代码并按照您的建议使用 $httpBackend 编写了测试,但由于某种原因它不起作用。我针对这个特定问题创建了另一个线程:stackoverflow.com/questions/13582308/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 2019-05-06
    • 2015-01-18
    • 2016-09-18
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多