AngularJS HTTP

时间:2016-07-18 08:26:09

标签: angularjs http mocking jasmine

我正在尝试测试通过服务执行http请求的控制器。

我应该只是模拟服务并返回默认值,而不是执行实际的http请求,或使用$httpBackend

顺便说一句,我在Jasmine进行测试。

感谢。

2 个答案:

答案 0 :(得分:0)

使用$httpBackend

因为您还需要模拟响应

$httpBackend.when("GET",'URL').respond(respnonse);

响应包含您期望的值。

答案 1 :(得分:0)

TL; DR 不要执行实际的http请求。

  • 单元测试
    在进行适当的单元测试时,您只测试一个单元。这可以是一个类,也可以只是一个类的一部分。这意味着您必须模拟依赖项。在你的情况下,这意味着你嘲笑服务只是像班级一样行事。所以返回包含数据模型的承诺 pro :真正的单元测试的最大优势是速度。您可以执行大量的单元测试,而不是单个端到端测试 con :单元测试的最大缺点是,当您将依赖项更改为以不同方式工作时,您的测试仍然会成功,因为该服务已被模拟。
  • INTEGRATION检验
    集成测试几乎是一个单元测试,但在这里你不要模拟直接依赖。在您的情况下,在进行集成测试时,您不会模拟服务,而是它的依赖项(使用$ httpBackend)。
    专业:仍然非常快,并提供更强大的测试。因为当您更新直接依赖项时,您测试的类可能会失败,因为它们不会被模拟 con :不如单元测试快,但仍然非常快。
  • END-TO-END
    E2E测试测试整个应用程序,而不是嘲笑任何东西。这包括对api的所有XHR调用 pro :由于没有任何模拟,它总是涵盖整个应用程序。跟踪DOM更改和浏览器兼容性非常有用。它甚至可以自动截取屏幕截图,以提供渲染数据的真实视图 con :它很慢。因为它执行实际的API调用,所以这些测试可能需要一段时间才能执行。

所以要回答你的问题,这取决于你的写作。当你编写适当的单元测试时,你应该模拟服务:

$provide.service('DataService', ['$q', function($q) { 
  this.get = function() {
    return $q(function(resolve, reject) {
      if (requestFailed) {
        reject('The request failed');
      }

      resolve(APIData);
    });
  };
}]);

如果您正在进行整合测试,则应使用$httpBackend模拟实际的$ http请求。

it('should request data', function() {
  $httpBackend
    .expect('GET', url)
    .respond(APIData);

  expect($scope.list.count).toEqual(0);

  $scope.clickRetrieve();
  $httpBackend.flush();

  expect($scope.list.count).toBeGreaterThan(0);
});

我正在开发一个相当大的应用程序,并且没有太多的测试经验。但我最喜欢的测试类型是迄今为止的集成测试。我在单元测试方面遇到了一些问题,这些问题没有显示出由于模拟服务导致的重大变化。由于我几乎只切换到集成测试,我几乎专门模拟我的数据服务。

旁注:我使用数据服务作为我的应用程序和API之间的层,如果API更新,理论上我应该只更新数据服务除了存储库访问这些类之外的类。 这样我可以确保在我的应用程序中我只使用DataModels而不是简单的对象,并且我使用undefined,而不是null