2017-01-23 15 views
1

私はAngular 2サービスをRxjs 5のAngular Httpサービスに接続し、快適なWeb​​サービスに接続しました。 getObjects呼び出しは、意味のあるオブジェクトのObservable配列の形式で、解析されたJsonを単に返します。私は私の嘲笑されたHTTP応答で解決するために観測された戻り値を取得しようとしてきましたが、私は実際これに対する実際の答えを見つけていません。Rxjs5 Angular 2のテスト

テストコード:

import { getTestBed } from '@angular/core/testing'; 
import { MockBackend } from '@angular/http/testing'; 
import { TestScheduler } from "rxjs"; 

import { expect } from 'chai'; 
import { spy } from 'sinon'; 
import TestingUtilities from "../shared/test.utilities"; 

import Service from './service'; 
import ReturnObject from "../returnobject"; 

describe(`ServiceTests`,() => { 
    let MOCK_DATA: string = ...mocked JSON string response...; 

    let service: Service 
    let backend: MockBackend 
    let scheduler: TestScheduler 

    function assertDeepEqualFrame(actual:any, expected:any) { 
    console.log("test"); 
    if (!expected === actual) { 
     throw new Error('Frames not equal!'); 
    } 
    } 

    beforeEach(() => { 
    TestingUtilities.configureTestingModuleForMockHttp(getTestBed(), function() { 
     return Service 
    }); 

    backend = getTestBed().get(MockBackend); 
    service = getTestBed().get(EarthquakeService); 
    scheduler = new TestScheduler(assertDeepEqualFrame); 
    }); 

    it('should return mocked data',() => { 
    TestingUtilities.mockHttpResponse(backend, MOCK_DATA); 

    let observables = service.getObjects(); 
    scheduler.expectObservable(observables).toBe("", functionToCreateMockObjects()); 
    }); 

TestingUtilitiesは、角度によって提供されるHTTPサービスをモックするための解決策の周りにだけ便利なラッパーはhttps://semaphoreci.com/community/tutorials/testing-angular-2-http-services-with-jasmineで提示されています。上のコードはコンパイルされていますが、実際にはObservableを返すようなことはありません。私はTestSchedulerを使って既存のサービスを呼び出し、監視のために観測情報を取得する方法を正確に把握することに苦労しています。誰にでもアイデアはありますか?

答えて

1

私はObservableをテストするためにTestSchedulerを使用しません。しかし、私は本当に私が使用して、次のアプローチのように:

import {TestBed, inject} from '@angular/core/testing'; 
import {BaseRequestOptions, Http, HttpModule, ResponseOptions, Response} from '@angular/http'; 
import {MockBackend} from '@angular/http/testing'; 
import {Book} from '../custom-types/book'; 
import {GoogleBooksService, API_PATH_SINGLE_BOOK} from './google-books.service'; 

const mockedHttpProvider = { 
    provide: Http, 
    deps: [MockBackend, BaseRequestOptions], 
    useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => { 
     return new Http(backend, defaultOptions); 
    } 
}; 

describe('Service: GoogleBooks',() => { 
    beforeEach(() => { 
     TestBed.configureTestingModule({ 
      imports: [HttpModule], 
      providers: [ 
       GoogleBooksService, 
       BaseRequestOptions, 
       MockBackend, 
       mockedHttpProvider 
      ], 
     }); 
    }); 

    it('should call the google books api', 
     inject([GoogleBooksService, MockBackend], (service: GoogleBooksService, backend: MockBackend) => { 
      let queryId: string = "someId"; 
      let expectedResponse: Book = { 
       description: 'It's just Angular', 
       title: 'How to test Observables' 
      }; 

      backend.connections.subscribe(connection => { 
       expect(connection.request.url).toBe(API_PATH_SINGLE_BOOK + queryId); 
       let response = new ResponseOptions({body: JSON.stringify(expectedResponse)}); 
       connection.mockRespond(new Response(response)); 
      }); 

      service.getBookByGoogleBookId(queryId).subscribe(response => { 
       expect(response).toEqual(expectedResponse); 
      }) 
     }) 
    ); 
}); 

サービスの実装:

@Injectable() 
export class GoogleBooksService { 

    constructor(private http: Http) { 
    } 

    getBookByGoogleBookId(id: string): Observable<Book> { 
     return this.http.get(API_PATH + id) 
      .map(res => res.json()); 
    } 
} 
+0

これは最終的に私が行った解決策です。私のエラーの理由は、私がHttpサービスの嘲笑を共有するように私のTestUtilitiesクラスをセットアップする方法でした。私は上記のURLからコピーして、URLを動的に修正するのを忘れてしまいました。これはすべての私の問題の原因となった。これを修正した後は、サービスコールの出力にサブスクライブするだけで残りの部分が削除されました。投稿ありがとう! – Skeeterdrums

0

嘲笑バックエンドとこのようにあなたのサービスをテストしてみてください。

describe(`ServiceTests`,() => { 
    let MOCK_DATA: string = ...mocked JSON string response...; 

    let earthquakeService: EarthquakeService; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     providers: [ 
      EarthquakeService, 
      { provide: XHRBackend, useClass: MockBackend }, 
      { provide: ComponentFixtureAutoDetect, useValue: true } 
     ], 
     imports: [ 
      HttpModule 
     ] 
    }) 
    .compileComponents(); 
    }); 
    }); 

    it('should return mocked data', async(inject([ Http, XHRBackend ], (http: Http, backend: MockBackend) => { 
    backend.connections.subscribe((c: MockConnection) => c.mockRespond(response)); 

    let options = new ResponseOptions({ status: 200, body: { data: MOCK_DATA } }); 
    response = new Response(options); 

    earthquakeService = new EarthquakeService(http); 

    earthquakeService.getObjects().subscribe(results => { 
     expect(results).toEqual({ data: MOCK_DATA }); 
    });); 

これはあなたのサービスをテスト孤立して。このサービスを使用する他のコンポーネントをテストするには、このフレームを拡張するか、それらのテストでスタブ付きサービスを作成します。

+0

これはTestUtilitiesラッパーの機能です。私が本当に必要だったのは、内部のアサーションを持つ購読ブロックでした。ありがとう! – Skeeterdrums