2016-06-22 6 views
3

私はkarma + jasmineを使ってサービスの約束をテストする方法を理解しようとしていますが、成功することはありません。今のところ、これは私が結果エラーでやったことです:angularjs 1 and jasmine、サービス約束テスト

PhantomJS 2.1.1 (Mac OS X 0.0.0) The FetchData service should fetch data FAILED 
    Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. 

なFetchDataサービス:

module.exports = function($http) { 
    return { 
     getFoo: function(id) { 
      return $http.get('https://api/' + id) 
         .then(function(result) { 
          return result.data; 
         }); 
     } 
    } 
}; 

テスト:私はそれをすることができないことがあります。この場合何かかしら

describe('The FetchData service', function() { 

    var dataFetcher; 

    beforeEach(angular.mock.module("myApp")) 

    beforeEach(inject(function(_dataFetcher_) { 
    dataFetcher = _dataFetcher_; 
    })); 

    it('should fetch data', function(done) { 

    var testData = function(res) { 
     expect(res.success).toBe(true); 
    }; 

    var failTest = function(error) { 
     expect(error).toBeUndefined(); 
    }; 

    dataFetcher.getFoo(id) 
     .then(testData) 
     .catch(failTest); 

    }); 
}); 

これを理解するのに役立ちます

ありがとう!

+0

https://docs.angularjs.org/api/ngMock/service/$httpBackend – Phil

答えて

1

$ httpサービスを模擬するためにテストに$ httpBackendサービスを注入する必要があります。

実際のHTTP呼び出しをモックするには、$ httpBackend.flushを呼び出す必要があります。 角度のドキュメントを確認してください。

編集。

it('should fetch data', function() { 

    var status, data; 
    function successCB(response){ 
    status = 'success'; 
    data = response.data; 
    } 
    function errorCB(){ 
    status = 'error' 
    } 
    //only pass the success and error callbacks here 
    dataFetcher.get(1).then(successCB, errorCB); 

    // you need to stop it  
    $httpBackend.flush(); 

    //assert for success 
    $httpBackend 
    .when('GET', 'https://api/1') 
    .respond(200, {foo:'bar'}); 

    expect(status).toEqual('success'); 
    expect(data).toEqual({foo: 'bar'}); 

    //assert for error 
    $httpBackend 
    .when('GET', 'https://api/1') 
    .respond(500, 'An error has occured.'); 

    expect(status).toEqual('success'); 

}); 
0

これは私は実際Angularjsドキュメントに基づいて、ここまでだソリューションです。

私はそれが自明(@のmehndraの答えやヒントに基づき更新)願っています:

describe('The FetchData service', function() { 

    var dataFetcher, $httpBackend; 

    beforeEach(angular.mock.module("myApp")); 

    beforeEach(inject(function(_dataFetcher_, _$httpBackend_) { 
     dataFetcher = _dataFetcher_; 
     $httpBackend = _$httpBackend_; 
    })); 

    afterEach(function() { 
     $httpBackend.verifyNoOutstandingExpectation(); 
     $httpBackend.verifyNoOutstandingRequest(); 
    }); 

    it('should fetch data', function() { 

     var status, data, 
      pid = 2140, 
      api = 'https://api'; 

     function successHandler(res){ 
      status = 'success'; 
      data = res.data; 
      expect(res.success).toEqual(true); 
      expect(status).toEqual('success'); 
     } 

     function errorHandler(){ 
      status = 'error' 
     } 

     $httpBackend 
     .when('GET', api + '/' + pid) 
     .respond({ success: true }); 

     $httpBackend 
     .when('GET', api + '/' + pid) 
     .respond(500, 'An error has occured.'); 

     dataFetcher.get(pid).then(successHandler, errorHandler); 

     $httpBackend.flush(); 

    }); 

}); 
+0

あなたのソリューションは、正しいと思われますしかし、私はあなたの主張がそれよりも少し良いと感じています。 テストでサービスコールの成功とエラーのハンドラを渡し、どちらが呼び出されたかを確認することができます。 私はちょうどそのコールバックでアサーションを避けたいです。 –

+0

@MahendraSinghの例がありますか? – punkbit

+0

編集を確認してください。 –

関連する問題