AngularのHttpを使うサービスの単体テスト
4系の話。Http
を使ってAPIアクセスするようなサービス(ここではPostService
)のテスト。もう一度同じものを書けと言われても無理だなと思ったので書いておく。
import { TestBed, inject, async } from '@angular/core/testing'; import { MockBackend, MockConnection } from '@angular/http/testing'; import { Http, Response, RequestMethod, ConnectionBackend, RequestOptions, BaseRequestOptions, ResponseOptions } from '@angular/http'; import { PostService, Post } from './post.service'; describe('PostService', () => { beforeEach(() => { TestBed.configureTestingModule({ providers: [ {provide: ConnectionBackend, useClass: MockBackend}, {provide: RequestOptions, useClass: BaseRequestOptions}, Http, PostService ] }); }); describe('fetchAll', () => { beforeEach(inject([ConnectionBackend], (mockBackend: MockBackend) => { mockBackend.connections.subscribe((connection: MockConnection) => { expect(connection.request.method).toEqual(RequestMethod.Get); connection.mockRespond(new Response(new ResponseOptions({ status: 200, body: { posts: [{content: "Hello"}, {content: "Goodbye"}] } }))); }); })); it('should return list of posts', async(inject([PostService], (service: PostService) => { service.fetchAll().subscribe((posts: Post[]) => { expect(posts[0].body).toEqual("Hello"); expect(posts[1].body).toEqual("Goodbye"); }); }))); }); });
テストコード中で投げたリクエストが、ConnectionBackend
のuseClass
に設定したMockBackend
のconnections
に流れてくるので、それに対する応答をbeforeEach
で設定している。リアクティブ。
あとはsubscribe
の中でexpect
することになるので、it
の第2引数をasync
で包むとこが忘れがちポイント。
Testing Angular 2 Services and Http with Jasmine などを参考にしました。