2016-10-11 3 views
0

私は自分のサービスと彼らが返すデータをテストしようとしています。私はAngular、Typescript、Karmaを使っています。これは私のサービスアングルで約束を返すサービスをテストする

/// <reference path="../../../typings/index.d.ts" /> 

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<{}> { 
    var self = this; 
    var deferred = this.$q.defer(); 

    this.$http.get('http://api.openweathermap.org/data/2.5/weather?' + params + '&appid=' + API_KEY) 
     .then((response) => { 
     deferred.resolve(response.data); 
     }, (errors) => { 
     self.$log.debug(errors); 
     deferred.reject(errors.data); 
     }); 

    return deferred.promise; 
    } 
} 

であり、これは私の主な質問はdeferred.promiseをテストし、受信したデータの構造をチェックする方法であるWeatherDataService.spec.ts

/// <reference path="../../../typings/index.d.ts" /> 

describe('WeatherDataService',() => { 
    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&lon=26.309871599999997').then((response) => { 
     expect(response).toBe('object'); 
     }); 
    }); 
    }); 
}); 

です。

______________________EDIT______________________

これは私がTypeError: undefined is not an object (evaluating '$http.get')を取得し、私はスペック

/// <reference path="../../../typings/index.d.ts" /> 

describe('WeatherDataServices',() => { 

    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)',() => { 
    $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); 
    }); 
}); 

で試すものです。私はちょうどweatherDataService.get(params)である私のサービスをテストしたいと思うし、それは私のコントローラで働く。

______________________EDIT______________________

これは私が提供する答えを取得していますエラーです。

Geolocation response should have a valid structure FAILED 
[email protected]_components/angular/angular.js:321:24 
[email protected]_components/angular/angular.js:4601:12 
[email protected]_components/angular/angular.js:4523:30 
[email protected]_components/angular-mocks/angular-mocks.js:3074:60 
[email protected]://localhost:9876/context.js:151:17 
bower_components/angular/angular.js:4641:53 
[email protected]_components/angular/angular.js:321:24 
[email protected]_components/angular/angular.js:4601:12 
[email protected]_components/angular/angular.js:4523:30 
[email protected]_components/angular-mocks/angular-mocks.js:3074:60 
[email protected]://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.<anonymous> 
(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. 
+0

'expect'を実行する方法は、後で$ rootScope。$ apply()を使ってダイジェストをトリガーすることです。 https://github.com/bvaughn/jasmine-promise-matchersは素晴らしい代替手段です。 Btwでは、コードは[遅延反パターン](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern)を使用しています。 – estus

+0

私はrootscopeを注入し、$ rootScopeを試しました。$ apply();それ以降は同じですが、それでも同じです。ソリューションを回答として投稿できますか? – Lexx

+0

私は答えとしてこれを追加しました。私は$ http要求が嘲笑されているところは見ません。実際の仕様が同じに見える場合、この理由で動作しません。 – estus

答えて

0

期待実行する方法は、その後$rootScope.$apply()または$rootScope.$digest()でダイジェストをトリガーすることです。

new WeatherDataService($http, $log, $q)で手動インスタンシエーションの代わりにweatherDataServiceを注入するほうがさらに有益です。味わいの問題かもしれませんが、手動アプローチの問題は、サービス注釈をテストしないことです。 Angularがこの仕事をあなたに任せましょう。

let $httpBackend, $rootScope; 

    beforeEach(inject(function (_$httpBackend_: ng.IHttpBackendService, _$rootScope_: ng.IRootScopeService) { 
    $httpBackend = _$httpBackend_; 
    $rootScope = _$rootScope_; 
    }); 

it('Geolocation response should have a valid structure', inject(function (weatherData) { 
    const params = 'lat=42.683529199999995&lon=26.309871599999997'; 
    const API_KEY = ...; 
    const url = 'http://api.openweathermap.org/data/2.5/weather?' + params + '&appid=' + API_KEY; 

    const responseMock = {}; 

    $httpBackend.whenGET(url).respond(responseMock); 
    weatherData.get(params).then((response) => { 
    expect(response).toBe(responseMock); 
    }); 

    // does $rootScope.$digest() internally 
    $httpBackend.flush(); 
    $httpBackend.verifyNoOutstandingRequest(); 
})); 

jasmine-promise-matchersは約束(彼らは本質的に上記のコードと同じようなことを行う)に包まれたアサーションに素敵な選択肢を提供します。

+0

今すぐ取得しています WeatherDataServiceテストカルマジオロケーションレスポンスに有効な構造が必要FAILEDエラー:予期しないリクエスト:GET http://api.openweathermap.org/data/2.5/weather?lat=42.683529199999995&lon=26.309871599999997 – Lexx

+0

https: //docs.angularjs.org/api/ngMock/service/$http $ httpをどのようにテストするべきかを示します。約束については、$ rootScope。$ digest()は、各約束の後にトリガーされるべきです。 – estus

+0

WeatherDataServiceをテストし、約束したコードを返すと思われるコード全体で回答を更新できますか? – Lexx

関連する問題