2017-01-23 85 views
1

我有一個Angular 2服務連接到Angular Http服務,使用Rxjs 5連接到一個寧靜的web服務。 getObjects調用只是以有意義對象的Observable數組的形式返回解析的Json。我一直試圖讓我的模擬Http響應返回observable來解決,但我還沒有真正找到一個工作的答案。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解決方案圍繞方便包裝。上面的代碼編譯,但它實際上並沒有返回嘲諷的Observables,也沒有聲明任何東西。我正在努力查看應該如何使用TestScheduler來調用現有服務並獲取可觀察對象以進行驗證。有人有主意嗎?

回答

1

我不使用TestScheduler來測試observables。但我真的很喜歡下面的辦法,我使用:

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

這是我最終解決的問題。我錯誤的原因是我設置TestUtilities類以共享Http服務的模擬方式:我從上面提到的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