茉莉测试角异步服务 [英] testing Angular async services with Jasmine

查看:133
本文介绍了茉莉测试角异步服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想测试茉莉真正的HTTP调用(集成测试),但是当我调用使用$ http.get,超时的方法和服务器不会被调用。

我知道,我应该注入的$ HTTP的实现,但不知道在哪里出现这种情况。

searchSvc

  app.service('searchSvc',['$ HTTP,$ Q',searchSvc]);
功能searchSvc($ HTTP,$ Q){
  返回{
    搜索:功能(文本){
      的console.log('svc.search调用,文本); //这也被调用
      返回$ q.when($ http.get('/搜索/'+文本));
    }
  };
}

searchSpec

 描述(searchTest功能(){
  VAR CTRL,SVC,$ HTTP;  beforeEach(函数(){
      模块('testApp');
    注(功能(_ $ controller_,searchSvc,_ $ HTTP _){
      CTRL = _ $ _控制器('searchCtrl');
      SVC = searchSvc;
      $ HTTP = _ $ HTTP;
    })
  });  它('测试服务器搜索'功能(完成){
      svc.search('重')。然后(功能(结果){
        的console.log('的承诺,然后'); //这个不会被调用,因为服务器不会被调用
        预期(结果).not.toBeNull();
        期待(result.data).not.toBeNull();
        期待(result.data.length).toBeGreaterThan(0);        完成();
      });
  });


解决方案

下面是我使用,使当我使用ngMock单元测试真正的HTTP调用的解决方案。我主要用它进行调试,通过测试工作,获得JSON的例子等。

我写了一个更详细的一篇关于我的博客解决方案:的如何进行单元测试使用ngMockE2E&放真正的HTTP调用;直通

的解决方案如下:

  angular.mock.http = {};angular.mock.http.init =功能(){  angular.module('ngMock',['NG','ngMockE2E'])。提供商({
    $ exceptionHandler的:angular.mock $ ExceptionHandlerProvider,
    $日志:$ angular.mock LogProvider,
    $区间:angular.mock $ IntervalProvider,
    $ rootElement的:angular.mock $ RootElementProvider
  })。配置(['$提供'功能($提供){
    $ provide.decorator('$超时',angular.mock $ TimeoutDecorator);
    $ provide.decorator('$$英国皇家空军,angular.mock $ RAFDecorator);
    $ provide.decorator('$$的AsyncCallback',angular.mock $ AsyncCallbackDecorator);
    $ provide.decorator('$ rootScope',angular.mock $ RootScopeDecorator);
    $ provide.decorator('$控制器,angular.mock $ ControllerDecorator);
  }]);};angular.mock.http.reset =功能(){  angular.module('ngMock',['NG'])。提供商({
    $浏览器:angular.mock $ BrowserProvider,
    $ exceptionHandler的:angular.mock $ ExceptionHandlerProvider,
    $日志:$ angular.mock LogProvider,
    $区间:angular.mock $ IntervalProvider,
    $ httpBackend:angular.mock $ HttpBackendProvider,
    $ rootElement的:angular.mock $ RootElementProvider
  })。配置(['$提供'功能($提供){
    $ provide.decorator('$超时',angular.mock $ TimeoutDecorator);
    $ provide.decorator('$$英国皇家空军,angular.mock $ RAFDecorator);
    $ provide.decorator('$$的AsyncCallback',angular.mock $ AsyncCallbackDecorator);
    $ provide.decorator('$ rootScope',angular.mock $ RootScopeDecorator);
    $ provide.decorator('$控制器,angular.mock $ ControllerDecorator);
  }]);};

包含ngMock后,这个源文件,例如:

 <脚本类型=文/ JavaScript的SRC =angular.js>< / SCRIPT>
<脚本类型=文/ JavaScript的SRC =角mocks.js>< / SCRIPT>
<! - 这将是源$ C ​​$ C只是提供 - >
<脚本类型=文/ JavaScript的SRC =ngMockHttp.js>< / SCRIPT>

如何编写测试?

 描述(HTTP测试,函数(){    beforeEach(模块('moviesApp'));    变量$控制器;
    变量$ httpBackend;
    变量$范围;    描述('真正的HTTP测试,函数(){      beforeEach(angular.mock.http.init);
      afterEach(angular.mock.http.reset);      beforeEach(注(功能(_ $ controller_,_ $ httpBackend_){
        $控制器= _ $ controller_;
        $范围= {};
        $ httpBackend = _ $ httpBackend_;        //注意,这个HTTP后端ngMockE2E的,将来会成为一个真正的HTTP请求
        $ httpBackend.whenGET('http://www.omdbapi.com/?s=terminator').passThrough();
      }));      它('应该加载默认的电影(与真正的HTTP请求),功能(完成){
        VAR moviesController = $控制器('MovieController',{$范围:$范围});        的setTimeout(函数(){
          期待($ scope.movi​​es).not.toEqual([]);
          完成();
        },1000);      });    });  });

它是如何工作?

它采用ngMockE2E的版本$ httpBackEndProvider,这为我们提供了的直通的功能,我们看到正在测试中使用。这确实顾名思义,让本机HTTP调用通过。

我们需要重新定义ngMock模块没有$ BrowserProvider它的仿版,因为这是prevents在单元测试中的实际HTTP调用使用ngMock。

I am trying to test a real http call with Jasmine (integration test), but when i call a method that uses $http.get, it times out and the server never gets called.

I know that I am supposed to inject the implementation of $http but not sure where that should happen.

searchSvc

app.service('searchSvc', ['$http', '$q', searchSvc]);
function searchSvc($http, $q) {
  return {
    search: function(text) {
      console.log('svc.search called with ', text); // this does get called 
      return $q.when($http.get('/search/' + text));
    }
  };
}

searchSpec

describe("searchTest", function() {
  var ctrl, svc, $http;

  beforeEach(function () {
      module('testApp');
    inject(function(_$controller_, searchSvc, _$http_){
      ctrl = _$controller_('searchCtrl');
      svc = searchSvc;
      $http = _$http_;
    })
  });

  it('test server search', function(done) {
      svc.search('re').then(function(result) {
        console.log('promise then'); // this never gets called, because server never gets called
        expect(result).not.toBeNull();
        expect(result.data).not.toBeNull();
        expect(result.data.length).toBeGreaterThan(0);

        done();
      });
  });

解决方案

Here is a solution that I use to make real HTTP calls when I'm using ngMock for unit tests. I mainly use it for debugging, working through the test, getting JSON examples etc.

I wrote a more detailed post about the solution on my blog: How to Unit Test with real HTTP calls using ngMockE2E & passThrough.

The solution is as follows:

angular.mock.http = {};

angular.mock.http.init = function() {

  angular.module('ngMock', ['ng', 'ngMockE2E']).provider({
    $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
    $log: angular.mock.$LogProvider,
    $interval: angular.mock.$IntervalProvider,
    $rootElement: angular.mock.$RootElementProvider
  }).config(['$provide', function($provide) {
    $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
    $provide.decorator('$$rAF', angular.mock.$RAFDecorator);
    $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
    $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
    $provide.decorator('$controller', angular.mock.$ControllerDecorator);
  }]);

};

angular.mock.http.reset = function() {

  angular.module('ngMock', ['ng']).provider({
    $browser: angular.mock.$BrowserProvider,
    $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
    $log: angular.mock.$LogProvider,
    $interval: angular.mock.$IntervalProvider,
    $httpBackend: angular.mock.$HttpBackendProvider,
    $rootElement: angular.mock.$RootElementProvider
  }).config(['$provide', function($provide) {
    $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
    $provide.decorator('$$rAF', angular.mock.$RAFDecorator);
    $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
    $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
    $provide.decorator('$controller', angular.mock.$ControllerDecorator);
  }]);

};

Include this source file after ngMock, for example:

<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="angular-mocks.js"></script>
<!-- this would be the source code just provided -->
<script type="text/javascript" src="ngMockHttp.js"></script>

How to write the test?

  describe('http tests', function () {

    beforeEach(module('moviesApp'));

    var $controller;
    var $httpBackend;
    var $scope;

    describe('real http tests', function() {

      beforeEach(angular.mock.http.init);
      afterEach(angular.mock.http.reset);

      beforeEach(inject(function(_$controller_, _$httpBackend_) {
        $controller = _$controller_;
        $scope = {};
        $httpBackend = _$httpBackend_;

        // Note that this HTTP backend is ngMockE2E's, and will make a real HTTP request
        $httpBackend.whenGET('http://www.omdbapi.com/?s=terminator').passThrough();
      }));

      it('should load default movies (with real http request)', function (done) {
        var moviesController = $controller('MovieController', { $scope: $scope });

        setTimeout(function() {
          expect($scope.movies).not.toEqual([]);
          done();
        }, 1000);

      });

    });

  });

How it works?

It uses ngMockE2E's version of $httpBackEndProvider, which provides us with the passThrough function we see being used in the test. This does as the name suggests and lets a native HTTP call pass through.

We need to re-define the ngMock module without its fake version of the $BrowserProvider, since that is what prevents the real HTTP calls in unit tests that use ngMock.

这篇关于茉莉测试角异步服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆