title: Testing service that returns promise in Angular
body: <p>I'm trying to test my services and the data they return. I'm using Angular, Typescript and Karma. This is my service</p>
  
  <pre><code>/// &lt;reference path="../../../typings/index.d.ts" /&gt;
  
  class WeatherDataService {
  
    static $inject = ['$http', '$log', '$q'];
  
    constructor(private $http: ng.IHttpService,
                private $log: ng.ILogService,
                private $q: ng.IQService) {
      this.$http = $http;
      this.$log = $log;
      this.$q = $q;
    }
  
    get(params: string): ng.IPromise&lt;{}&gt; {
      var self = this;
      var deferred = this.$q.defer();
  
      this.$http.get('http://api.openweathermap.org/data/2.5/weather?' + params + '&amp;appid=' + API_KEY)
        .then((response) =&gt; {
          deferred.resolve(response.data);
        }, (errors) =&gt; {
          self.$log.debug(errors);
          deferred.reject(errors.data);
        });
  
      return deferred.promise;
    }
  }
  </code></pre>
  
  <p>And this is the WeatherDataService.spec.ts</p>
  
  <pre><code>/// &lt;reference path="../../../typings/index.d.ts" /&gt;
  
  describe('WeatherDataService', () =&gt; {
    let weatherDataService;
  
    var $http, $log, $q;
  
    beforeEach(angular.mock.module('app'));
  
    beforeEach(inject(function (_$http_: ng.IHttpService, _$log_: ng.ILogService, _$q_: ng.IQService) {
      $http = _$http_;
      $log = _$log_;
      $q = _$q_;
  
      weatherDataService = new WeatherDataService($http, $log, $q);
    }));
  
    describe('testing karma', function () {
      it('Geolocation response should have a valid structure', function () {
        weatherDataService.get('lat=42.683529199999995&amp;lon=26.309871599999997').then((response) =&gt; {
          expect(response).toBe('object');
        });
      });
    });
  });
  </code></pre>
  
  <p>My main question is how to test the deferred.promise and check the structure of the received data.</p>
  
  <p><strong>______________________EDIT______________________</strong></p>
  
  <p>This is what I try in the spec</p>
  
  <pre><code>/// &lt;reference path="../../../typings/index.d.ts" /&gt;
  
  describe('WeatherDataServices', () =&gt; {
  
    let weatherDataService;
  
    beforeEach(angular.mock.module('app'));
  
    beforeEach(angular.mock.module('weatherDataService'));
  
    var service, $httpBackend, $http,
      $scope = {valid: true, response: {}};
  
    beforeEach(inject(function ($injector: ng.auto.IInjectorService) {
      service = $injector.get('WeatherDataService');
      $httpBackend = $injector.get('$httpBackend');
      $http = $injector.get('$http');
    }));
  
    it('should demonstrate using when (200 status)', () =&gt; {
      $http.get('http://jsonplaceholder.typicode.com/users')
        .success(function(data: any) {
          $scope.valid = true;
          $scope.response = data;
        })
        .error(function(data: any) {
          $scope.valid = false;
        });
  
      expect($scope.valid).toBe(true);
    });
  });
  </code></pre>
  
  <p>I get <code>TypeError: undefined is not an object (evaluating '$http.get')</code>. I just want to test my service that is <code>weatherDataService.get(params)</code> and it works in my controller.</p>
  
  <p><strong>______________________EDIT______________________</strong></p>
  
  <p>This is the error that I'm getting with the provided answer.</p>
  
  <pre><code>Geolocation response should have a valid structure FAILED
  forEach@bower_components/angular/angular.js:321:24
  loadModules@bower_components/angular/angular.js:4601:12
  createInjector@bower_components/angular/angular.js:4523:30
  workFn@bower_components/angular-mocks/angular-mocks.js:3074:60
  loaded@http://localhost:9876/context.js:151:17
  bower_components/angular/angular.js:4641:53
  forEach@bower_components/angular/angular.js:321:24
  loadModules@bower_components/angular/angular.js:4601:12
  createInjector@bower_components/angular/angular.js:4523:30
  workFn@bower_components/angular-mocks/angular-mocks.js:3074:60
  loaded@http://localhost:9876/context.js:151:17
  bower_components/angular/angular.js:4641:53
  PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.006 secs / 0.014 secs)
  [15:24:52] 'karma:single-run' errored after 2.26 s
  [15:24:52] Error: Failed 1 tests.
  at failCount (F:\var\www\compucorp\task1\gulp_tasks\karma.js:13:22)
  at removeAllListeners
  (F:\var\www\compucorp\task1\node_modules\karma\lib\server.js:379:7)
  at Server.&lt;anonymous&gt;
  (F:\var\www\compucorp\task1\node_modules\karma\lib\server.js:390:9)
  at Server.g (events.js:286:16)
  at emitNone (events.js:91:20)
  at Server.emit (events.js:185:7)
  at emitCloseNT (net.js:1548:8)
  at _combinedTickCallback (internal/process/next_tick.js:71:11)
  at process._tickDomainCallback (internal/process/next_tick.js:122:9)
  [15:24:52] 'test' errored after 3.87 s
  npm ERR! Test failed.  See above for more details.
  </code></pre>