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 などを参考にしました。
ReDocに食わせるOpenAPIにはoperationIdを書こう
最近ReDocを触っていてヤヤハマリに遭遇することがあるので書いておきます。
operationId
ってなにさというと、OpenAPIのOperation Objectの一項目で、操作を識別するための一意な文字列のことです。ReDocに食わせるOpenAPIには、と書きましたが、そうでなくても書いておくべきやつです。
困ったこと
v1.14.0の話です。
ReDocのデモを見るとわかりますが、例えばaddPet
というoperationIdが付いた操作には、パーマリンクとして
http://rebilly.github.io/ReDoc/#operation/addPet が与えられます。operationIdをちゃんと書いたときはいいのですが、ここをサボると、ReDocは他の情報から頑張って一意な文字列を作ろうとします。健気なやつです。ただその文字列が、
/#null%2Fpaths%2F~1v1~1pet.json%2Fget
みたいな。せっかく頑張ってくれたんですが、ちょっと積極的に使う気になれない。しかも場所によって先頭のnull
がundefined
になってリンクとして機能しないっていう…。ということで、operationIdはサボらずちゃんと書きましょう。
minikubeを触った
ふとkubernetesを触ってみようと思い、ローカルで試すにはminikubeがよいということで試してみた。一通りチュートリアルをやってわかった気になったので、ちょっとした構成をつくってみたのがこちら。
docker hubに上げてないイメージを使うために
$ minikube start $ eval $(minikube docker-env)
とかしないといけないはず。これをした上で、
$ ./build.sh
とすると、docker build
やらDeploymentの作成が行われ、以下が2組立ち上がる。
- 80番を3000番にリバースプロキシするnginx
- 今の時刻を文字で返すWebアプリ
$ ./build.sh Sending build context to Docker daemon 5.718MB Step 1 : FROM golang:alpine ---> c82f63bb2928 Step 2 : ADD . /tmp ---> Using cache ---> be2da95d39d6 Step 3 : WORKDIR /tmp ---> Using cache ---> 153c17f1ff46 Step 4 : RUN go build -o /opt/app app.go ---> Using cache ---> d70e89cd9650 Step 5 : ENTRYPOINT /opt/app ---> Using cache ---> f48256763296 Successfully built f48256763296 Sending build context to Docker daemon 3.584kB Step 1 : FROM nginx:latest ---> 5766334bdaa0 Step 2 : COPY ./nginx.conf /etc/nginx/ ---> Using cache ---> d71e8a6ed75d Successfully built d71e8a6ed75d deployment "current-time" created service "current-time" exposed open 192.168.99.100:31744
最後に出力されているURLへ行くと、"2017-04-23 08:11:50.512403779 +0000 UTC"
という感じが見えて、動いていることが確認できる。