2016-03-29 7 views
1

モジュール定義- httpBackendでHTTPサービスをテストするには、予期しない例外をスローし

var module = angular.module('test', []); 
module.provider('client', function() { 
    this.$get = function($http) { 
     return { 
      foo: function() { 
       return $http.get('foo'); 
      } 
     } 
    } 
}); 

module.factory('service', ['client', function(client) { 
    return { 
     bar: function() { 
      return client.foo(); 
     } 
    } 
}]); 

基本的には、クライアントはHTTP呼び出しのラッパーであり、サービスは、クライアントの基本的な機能のラッパーです。

私はkarma + jasmineでプロバイダとサービスの両方をテストしています。予想通り、プロバイダのテストが実行されますが、私は、サービス・テストに問題がある:

describe('service test', function(){ 
    var service = null; 
    beforeEach(function(){ 
     module('test') 

     inject(function(_service_, $httpBackend, $injector) { 
      service = _service_; 
      $httpBackend = $injector.get('$httpBackend'); 
     }); 
    }); 

    it('should invoke client.foo via service.bar', function() { 
     $httpBackend.expect("GET", "foo"); 
     service.bar(); 
     expect($httpBackend.flush).not.toThrow(); 
    }); 

}); 

私はExpected function not to throw, but it threw Error: No pending request to flush !.を取得します。同じ方法でプロバイダをテストする場合、このテストは合格になります。どうして?

+1

ん[この](http://stackoverflow.com/a/19586921/771848が)助けて? – alecxe

+2

あなたの 'beforeEach()'で何かが怪しいように見える... beforeEachは '$ httpBackend'の引数を取得し、その引数を' $ httpBackend = $ injector.get( '$ httpBackend'); 'で上書きします。あなたが示したコードから、 '$ httpBackend'は' it() 'ブロックの中で' undefined 'のように見えます。 –

答えて

1

サービスをテストするときは、クライアントをモックし、実際のクライアントの代わりにそのモックを注入する必要があります。あなたのモックは、このサービスをテストするためにのみ使用することが期待される場合は同じファイルに、別の場所でもう一度使用する場合は別のファイルに入れることができます。このようにするには、$ httpBackendを使用する必要はありません(実際にhttp呼び出しを行っているわけではないため)が、約束を解決するためにスコープを使用する必要があります。

モッククライアント:モックを使用して

angular.module('mocks.clientMock', []) 
    .factory('client', ['$q', function($q) { 
     var mock = { 
      foo: function() { 
       var defOjb = $q.defer(); 
       defOjb.resolve({'your data':'1a'}); 
       return defOjb.promise; 
      } 
     }; 
     return mock; 
    }]); 

describe('service test', function(){ 
    var service, mock, scope; 
    beforeEach(function(){ 
     module('test', 'mocks.clientMock'); 

     inject(function(_service_, $rootScope) { 
      service = _service_; 
      scope = $rootScope.$new(); 
     }); 
    }); 

    it('should invoke client.foo via service.bar', function() { 
     spyOn(client, 'foo').and.callThrough(); 
     service.bar(); 
     scope.$digest(); 
     expect(client.foo).toHaveBeenCalled(); 
    }); 
}); 
関連する問題