質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

454閲覧

Handlerの単体テスト(UT)について

NakaShun_1129

総合スコア20

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2020/08/28 05:56

編集2020/08/28 07:33

こんにちは。

現在サービルの開発をしており、handlerの単体テストが必要なのですがいまいちやり方がわからなくて止まってしまっています。
Handlerの仕様は以下のようになってます。

  • POSTリクエストに対してバリデーションを実行
  • リクエストに対して適切なサービスを実行

今回やりたいこと

  • GetリクエストのbodyにIDがあったらgetUserServiceを呼び出す(これはできています)
  • Postリクエストに対してvalidatinoチェックを行い、問題があればエラーを返す(これが分かりません)

テストの中で作成したFakeEventのbodyをvalidationチェックをする方法がいまいち分かりません。
どこに書けばいいのかも正直分かりません。

ヒントでもなんでもいいのでアドバイスをいただけたらなと思います。
よろしくお願いします。

------追記------
validationチェックはできました!!
あとはエラーを受け取るだけです。

  • validationがOKだった時にStatusCode200を受け取りたいです。
  • エラーがあった場合にはStatusCode400を受け取りたいです。

現状のコード

UserRestHandler.spec.ts

1 2import "reflect-metadata"; 3import { UserRestHandler } from "@src/presentation/handler/users/UserRestHandler"; 4import Request from "@src/presentation/dto/request/Request"; 5import { ObjectLiteral } from "typeorm"; 6import * as Response from "@src/presentation/dto/response/Response"; 7 8const validationSchemePost = require("../../../../assets/schema/UserPostRequestSchema.json"); 9 10 11describe("UserRestHandler", () => { 12 test("get calls single get service if id is passed", async () => { 13     //requestbodyにIDがあったらfakeGetUserService 14 const fakeGetUsersService = {} as any; 15 const fakeGetUserService = { 16 execute: jest.fn(), 17 } as any; 18 const fakeCreateUserService = {} as any; 19 const handler = new UserRestHandler( 20 fakeGetUsersService, 21 fakeGetUserService, 22 fakeCreateUserService 23 ) as any; 24 const fakeEvent = { 25 httpMethod: "GET", 26 pathParameters: { 27 id: 1, 28 }, 29 }; 30 const fakeContext = {}; 31 const response = handler.handle(fakeEvent, fakeContext); 32 }); 33 34 test("Type validation", async () =>{ 35 //型をチェック 36 const fakeGetUsersService = {} as any; 37 const fakeGetUserService = { 38 execute: jest.fn(), 39 } as any; 40 const fakeCreateUserService = {} as any; 41 const handler = new UserRestHandler( 42 fakeGetUsersService, 43 fakeGetUserService, 44 fakeCreateUserService 45 ) as any; 46 const fakeEvent = { 47 httpMethod: "POST", 48 pathParameters: { 49 // これをValidationチェックしたい 50 email: "example@example.com", 51 name: "John Smith", 52 gender: "man", 53 date_of_birth: null, 54 nationality_code: "US", 55 is_root: true, 56 uid: "0000-000000-000000-0000", 57 organization: "example", 58 is_organization_manager:false, 59 role: "organization-manager", 60 status: "Busy", 61 department: null, 62 title: null, 63 workable_hours_per_week: 40, 64 workable_hours_per_month: 160, 65 tags: [ 66 {tag:"tag1"}, 67 {tag:"tag2"}, 68 {tag:"tag3"} 69 ] 70 }, 71 }; 72 const fakeContext = {}; 73 const fakeContext = {}; 74 const eventBody = fakeEvent.pathParameters; 75 const validationSchemePost = require("../../../../assets/schema/UserPostRequestSchema.json"); 76 const body: ObjectLiteral = new Request( 77 eventBody, 78 validationSchemePost! 79 ).validate(); 80 }) 81});
//RestHandler.ts import { APIGatewayEvent, Context } from "aws-lambda"; import { ObjectLiteral } from "typeorm"; import * as Response from "../dto/response/Response"; import Request from "../dto/request/Request"; import { injectable, unmanaged } from "inversify"; @injectable() export default abstract class RestHandler<T> { protected validationSchemePost: string | null; protected validationSchemePut: string | null; protected doPost: boolean; protected doPut: boolean; protected doGet: boolean; protected doDelete: boolean; protected event: APIGatewayEvent | null = null; protected context: Context | null = null; protected resourcePath: string | null = null; constructor( @unmanaged() validationSchemePost: string | null, @unmanaged() validationSchemePut: string | null, @unmanaged() doPost: boolean, @unmanaged() doPut: boolean, @unmanaged() doGet: boolean, @unmanaged() doDelete: boolean ) { this.validationSchemePost = validationSchemePost; this.validationSchemePut = validationSchemePut; this.doPost = doPost; this.doPut = doPut; this.doGet = doGet; this.doDelete = doDelete; } public async handle(event: APIGatewayEvent, context: Context) { if (!event || !context) { throw new Error("APIEvent information missing"); } this.event = event; this.context = context; this.resourcePath = event.resource; switch (this.event.httpMethod) { case "GET": if (!this.doGet) return this.unhandledMethod(); return await this._get(); case "POST": if (!this.doPost) return this.unhandledMethod(); return await this._post(); case "PUT": if (!this.doPut) return this.unhandledMethod(); return await this._put(); case "DELETE": if (!this.doDelete) return this.unhandledMethod(); return await this._delete(); default: return this.unhandledMethod(); } } protected async _get() { let response; try { const id = this.event!.pathParameters ? this.event!.pathParameters.id : false; // TODO: fix typing implementation const result = await (id ? this.getById!(id) : this.get!()); response = new Response.GetResponse(result).create(); } catch (error) { // check for not found, etc response = new Response.GeneralErrorResponse( error, this.context!.awsRequestId ).create(); } return response; } protected async _post() { let response; try { const eventBody = JSON.parse(this.event!.body!.toString()); const body: ObjectLiteral = new Request( eventBody, this.validationSchemePost! ).validate(); const result = await this.post!(body); response = new Response.PostResponse( result, this.resourcePath! ).create(); } catch (error) { // check for not found, etc response = new Response.GeneralErrorResponse( error, this.context!.awsRequestId ).create(); } return response; } private async _put() {} private async _delete() {} abstract async getById?(id: any): Promise<T>; abstract async get?(): Promise<T[]>; abstract async post?(body: any): Promise<any>; abstract async put?(): Promise<any>; abstract async delete?(): Promise<any>; // TODO: implement response type protected unhandledMethod(): any { return new Response.NotImplementedError( "Unsupported HTTP method(" + this.event!.httpMethod + ")", this.context!.awsRequestId ).create(); } }
//UserRestHandler.ts import { UserResponse } from "@src/model/repository/user/UserMap"; import { UserPostRequest } from "../users/UserPostRequest"; import RestHandler from "../RestHandler"; import IUserRestHandler from "./IUserRestHandler"; import { injectable, inject } from "inversify"; import { TYPES } from "@src/constants/types"; const validationSchemePost = require("../../../../assets/schema/UserPostRequestSchema.json"); // service (use case) interfaces import IGetUsersService from "@src/application/service/users/getUsers/IGetUsersService"; import IGetUserService from "@src/application/service/users/getUser/IGetUserService"; import ICreateUserService from "@src/application/service/users/createUser/ICreateUserService"; @injectable() export class UserRestHandler extends RestHandler<UserResponse> implements IUserRestHandler { private getUsersService: IGetUsersService; private getUserService: IGetUserService; private createUserService: ICreateUserService; constructor( @inject(TYPES.GetUsersService) getUsersService: IGetUsersService, @inject(TYPES.GetUserService) getUserService: IGetUserService, @inject(TYPES.CreateUserService) createUserService: ICreateUserService ) { super(validationSchemePost, null, true, true, true, true); this.getUsersService = getUsersService; this.getUserService = getUserService; this.createUserService = createUserService; } public async getById(id: number) { return await this.getUserService.execute(id); } public async get() { return await this.getUsersService.execute(); } public async post(request: UserPostRequest) { return await this.createUserService.execute(request); } // implement public put: undefined; public delete: undefined; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2020/08/28 09:34

> 現在サービルの開発をしており、handlerの単体テストが必要なのですがいまいちやり方がわからなくて止まってしまっています。 サービル????
guest

回答1

0

自己解決

一旦閉じます。

複雑に考えていました。
他のファイルでvalidationをかけていたので、ここではvalidationに引っかかるbodyを送信してエラーが返ってくるかを確認するだけでした。

投稿2020/09/04 09:09

NakaShun_1129

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問