【问题标题】:how is angular mock's httpBackend passed implicitly to the $controller service in tests?angular mock 的 httpBackend 如何在测试中隐式传递给 $controller 服务?
【发布时间】:2016-10-19 20:38:22
【问题描述】:

这个规范通过了,尽管它看起来应该失败。 (代码来自一本关于角度和轨道的书)

这是 Angular 应用程序:

var app = angular.module('customers',[]);

app.controller("CustomerSearchController",
  ["$scope", "$http", function($scope, $http) {
    var page = 0;
    $scope.customers = [];
    $scope.search = function (searchTerm) {
      if (searchTerm.length < 3) {
        return;
      }
      $http.get("/customers.json",
        { "params": { "keywords": searchTerm, "page": page } }
      ).then(function(response) {
          $scope.customers = response.data;
        },function(response) {
          alert("There was a problem: " + response.status);
        }
      );
    };
  }
]);

还有,这里是 Jasmine 规格:

describe("Error Handling", function () {
  var scope = null,
    controller = null,
    httpBackend = null;
  beforeEach(module("customers"));
  beforeEach(inject(function ($controller, $rootScope, $httpBackend) {
    scope = $rootScope.$new();
    httpBackend = $httpBackend;
    controller = $controller("CustomerSearchController", {
      $scope: scope
    });
  }));
  beforeEach(function () {
    httpBackend.when('GET', '/customers.json?keywords=bob&page=0').respond(500, 'Internal Server Error');
    spyOn(window, "alert");
  });
  it("alerts the user on an error", function() {
    scope.search("bob");
    httpBackend.flush();
    expect(scope.customers).toEqualData([]);
    expect(window.alert).toHaveBeenCalledWith(
      "There was a problem: 500");
    });

});

我不明白控制器是如何访问 $httpBackend 服务的,它被注入到传递给 beforeEach 方法的匿名函数中。传入了 $scope 服务,但没有传入 httpBackend。

【问题讨论】:

    标签: angularjs dependency-injection httpbackend angular-mock


    【解决方案1】:

    $controller 不依赖于$httpBackend 服务,$httpBackend 不会传递给它。

    $httpdepends on $httpBackend(因此得名)。 $httpBackend 在 ngMock with mocked implementation 中被覆盖,并由 $http 使用,而不是 original $httpBackend(不适合直接使用)。

    【讨论】:

      【解决方案2】:

      在您的代码中:

      app.controller("CustomerSearchController", ["$scope", "$http", 函数($scope, $http) { ... }] )

      您要求 Angular 将其存档的 $http 注入您的控制器。您没有在此处提供本地覆盖

      控制器 = $controller("CustomerSearchController", { $范围:范围 });

      所以 Angular 用它所拥有的来满足你的注入请求。正如@estus 所说,ngMock 中提供的覆盖本身被注入了 $httpBackend,您在测试中已将其配置为以某种方式运行..

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-02
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多