首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在AngularJS单元/集成测试中向HTTP服务器发出实际请求

在AngularJS单元/集成测试中向HTTP服务器发出实际请求
EN

Stack Overflow用户
提问于 2017-02-19 19:08:36
回答 1查看 1.3K关注 0票数 4

在角1.x单元/集成测试中,发出未被$httpBackend.when模拟的请求会导致错误:

错误:意外请求:获取/实请求

是否有可能使用ngMock和Karma+Jasmine测试平台发出真正的HTTP请求?做这件事的好方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-19 19:11:37

AngularJS是一个自以为是的框架,它在单元测试中对HTTP请求的看法是,所有这些请求都应该被模拟。

出于两个原因,在单元测试中执行真正的HTTP请求是不可取的。单元测试应该是隔离的和快速的。发出真正的请求会导致测试异步,这会显著降低测试的运行速度。真正的请求打破了隔离,如果测试通过取决于测试单元和后端。

在设计AngularJS ngMock模块时考虑到了这一点(它是由角-mocks.js在单元测试中自动加载的)。开发人员几乎不会用角度进行异步 Jasmine单元测试,因为没有必要这样做。

集成测试各不相同。它们可能不如E2E测试(通常由Protractor运行)和测试几个单元是如何协同工作的,这可能包括一个后端(HTTP )。因此,最终仍然使用Karma和Jasmine,但是测试可能比较慢,而且是异步的,并且可以执行真正的HTTP请求。

这就是ngMockE2E模块(通常用于E2E测试)的开始位置。它与ngMock一起包含在角mocks.js中,但默认情况下不加载。

ngMockE2E是一个AngularJS模块,包含适合端到端测试的模拟.目前,这个模块中只有一个模拟-- e2e $httpBackend模拟。

ngMockE2E包含不同的$httpBackend实现,可用于此目的。它的API各不相同。它不应该使用flushextend方法。如果存在应该执行的$rootScope.$digest()承诺链,则可以使用$q

ngMockE2E将无法正常工作,因为ngMock在使用其助手函数moduleinject时对棱角服务进行了调整。可以使用用于集成测试的辅助模块:

代码语言:javascript
运行
复制
angular.module('ngMockI9n', []).config(function ($provide) {
  // hack to restore original implementations which were overridden by ngMock
  angular.injector(['ng', function ($httpBackendProvider, $browserProvider) {
    $provide.provider('$httpBackend', $httpBackendProvider);
    $provide.provider('$browserI9n', $browserProvider);
  }]);

  // make ngMockE2E $httpBackend use original $browser
  var httpBackendI9nDecorator = angular.mock.e2e.$httpBackendDecorator
  .map(function (dep) {
    return (dep === '$browser') ? '$browserI9n' : dep;
  });
  $provide.decorator('$httpBackend', httpBackendI9nDecorator);
});

此外,可以使用白名单的真实HTTP请求的配方来简化测试,尽管最佳实践是显式地枚举真实的和模拟的请求。

代码语言:javascript
运行
复制
beforeEach(module('app'));  
beforeEach(module('ngMockI9n'));

beforeEach(inject(function ($httpBackend) {
  $httpBackend.when('GET', '/mocked-request').respond(200, {});

  // all other requests will be automatically whitelisted and treated as real
  // so make sure that mocked requests are mocked above this point
  angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD', 'PUT', 'POST', 'PATCH'],
  function (method) {
    $httpBackend.when(method).passThrough();
  });
}));


it('does real async request', function (done) {
  // async tests need extra `done` param
  inject(function () {
    $http.get('real-request').then(function (response) {
      expect(response.data).toEqual(...);
    })
    .then(done, done.fail);

    $rootScope.$digest();
  });
});

it('does mocked sync request', function (done) {
  // tests with mocked requests are async, too
  inject(function () {
    $http.get('mocked-request').then(function (response) {
      expect(response.data).toEqual(...);
    })
    .then(done, done.fail);

    $rootScope.$digest();
  });
});

在实际请求的集成测试中使用来自$httpBackend ngMockE2E 的,这需要一些额外的工作才能使其与 ngMock**.兼容。永远不要在单元测试中执行真正的请求,这会导致缓慢和无用的测试。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42331583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档