見出し画像

AngularなApolloのテストツールがよくできていてびっくり。

Angularアプリケーションのテストコードを書いています。

サービスクラスのテストコードを書いていて、Apolloの部分のモックを作ろうと思い、念のためApolloのサイトに行ってみると、テストツールが準備されていました。

テストするサービスクラス

テストするサービスはこちらです。

import { Injectable } from '@angular/core';

import { Apollo } from 'apollo-angular';

import { Observable } from 'rxjs';

import { environment } from '../../environments/environment';

import { MEMBERS, REGIST_MEMBER, DELETE_MEMBER } from './member.graphql';

import { Member } from './member';

@Injectable({
 providedIn: 'root'
})
export class MemberService {

 constructor(
   private readonly apollo: Apollo,
 ) { }

 /**
  * すべてのメンバーを取得する
  */
 getAll(): Observable<Member[]> {
   return new Observable<Member[]>((observer) => {
     // APIサーバーからメンバー情報を取得する
     this.apollo.watchQuery({
       query: MEMBERS,
     })
     .valueChanges
     .subscribe(
       (res: any) => {
         observer.next(res.data.members);
       },
       err => {
         observer.error(err);
       },
     );
   });
 }
}

GraphQLのタグは外出しにしています。

import gql from 'graphql-tag';

/**
* メンバー取得クエリー
*/
export const MEMBERS = gql`
 query members {
   members {
     memberId
     auth0UserId
     name
     email
     role
     companyName
     department
     memo
   }
 }
`;

テストコード

テストを実行するコードはこちらです。

ApolloTestingControllerを使うと、watchQueryの呼び出しをシュミレートしてくれます。

executeOneでgqlを投げて、返ってきたオブジェクトで返ってくるべきデータをflushすれば、そのデータがwatchQueyの復帰値として返ってくる仕組みです。

import { TestBed } from '@angular/core/testing';
import { ApolloTestingModule, ApolloTestingController } from 'apollo-angular/testing';

import { MemberService } from './member.service';
import { MEMBERS } from './member.graphql';

describe('MemberService', () => {
   let memberService: MemberService;
   let controller: ApolloTestingController;
   
   beforeEach(() => {
       TestBed.configureTestingModule({
           imports: [
               ApolloTestingModule,
           ],
       });

       memberService = TestBed.inject(MemberService);
       controller = TestBed.get(ApolloTestingController);
   });
   
   it('should be created', () => {
       expect(memberService).toBeTruthy();
   });
   
   it('Test: getAll', () => {
       // テストメソッドを呼び出す
       memberService.getAll()
       .subscribe(m => {
           // 2件取得できたらOK
           expect(m.length).toEqual(2);
       });

       // members Queryを呼び出す
       const op = controller.expectOne(MEMBERS);

       // member Queryの結果を返す
       op.flush({
           data: {
               members: [
                   {
                       memberId: 0,
                       auth0UserId: 'test0',
                       name: 'test0',
                       email: 'test0',
                       role: 100,
                       companyName: 'test0',
                       department: 'test0',
                       memo: 'test0',
                   },
                   {
                       memberId: 1,
                       auth0UserId: 'test1',
                       name: 'test1',
                       email: 'test1',
                       role: 20,
                       companyName: 'test1',
                       department: 'test1',
                       memo: 'test1',
                   },
               ],
           },
       });

       // テストを実行する
       controller.verify();
   });
});

Apollo(GraphQL)をいじり始めて、2年が経ちますが、どんどん進化しています。

こういう進化はいじっていて楽しいですね!

この記事が気に入ったらサポートをしてみませんか?