[{"data":1,"prerenderedAt":2263},["ShallowReactive",2],{"post-jest-nestjs-e2e-testing":3},{"id":4,"title":5,"body":6,"date":2249,"description":2250,"extension":2251,"meta":2252,"navigation":749,"path":2259,"seo":2260,"stem":2261,"__hash__":2262},"blog\u002Fblog\u002Fjest-nestjs-e2e-testing.md","NestJS + JestでE2Eテスト環境を構築する",{"type":7,"value":8,"toc":2226},"minimark",[9,13,17,20,31,35,39,42,184,187,215,226,230,240,490,500,507,510,532,540,544,547,550,556,559,653,657,660,1140,1143,1711,1714,2149,2152,2167,2170,2176,2180,2186,2189,2192,2219,2222],[10,11,12],"h2",{"id":12},"はじめに",[14,15,16],"p",{},"NestJSでJestを使ったE2Eテストを導入した際の知見をまとめます。",[10,18,19],{"id":19},"ディレクトリ構造",[21,22,27],"pre",{"className":23,"code":25,"language":26},[24],"language-text","e2e\u002F\n├── users.e2e-spec.ts\n├── jest-e2e.json\n├── mocks\u002F\n│   └── contractorReps\u002F\n│       └── mock.ts\n└── utilities\u002F\n    ├── common.utility.ts\n    └── master.utility.ts\n","text",[28,29,25],"code",{"__ignoreMap":30},"",[10,32,34],{"id":33},"jest設定","Jest設定",[36,37,38],"h3",{"id":38},"設定ファイルの作成",[14,40,41],{},"E2Eテスト用のJest設定を作成します。",[21,43,47],{"className":44,"code":45,"language":46,"meta":30,"style":30},"language-json shiki shiki-themes github-light github-dark","{\n  \"moduleFileExtensions\": [\"js\", \"json\", \"ts\"],\n  \"rootDir\": \".\",\n  \"testEnvironment\": \"node\",\n  \"testRegex\": \".e2e-spec.ts$\",\n  \"transform\": {\n    \"^.+\\\\.(t|j)s$\": \"ts-jest\"\n  },\n  \"moduleNameMapper\": {\n    \"^src\u002F(.*)$\": \"\u003CrootDir>\u002F..\u002F..\u002F$1\"\n  }\n}\n","json",[28,48,49,58,86,101,114,127,136,147,153,161,172,178],{"__ignoreMap":30},[50,51,54],"span",{"class":52,"line":53},"line",1,[50,55,57],{"class":56},"sVt8B","{\n",[50,59,61,65,68,72,75,78,80,83],{"class":52,"line":60},2,[50,62,64],{"class":63},"sj4cs","  \"moduleFileExtensions\"",[50,66,67],{"class":56},": [",[50,69,71],{"class":70},"sZZnC","\"js\"",[50,73,74],{"class":56},", ",[50,76,77],{"class":70},"\"json\"",[50,79,74],{"class":56},[50,81,82],{"class":70},"\"ts\"",[50,84,85],{"class":56},"],\n",[50,87,89,92,95,98],{"class":52,"line":88},3,[50,90,91],{"class":63},"  \"rootDir\"",[50,93,94],{"class":56},": ",[50,96,97],{"class":70},"\".\"",[50,99,100],{"class":56},",\n",[50,102,104,107,109,112],{"class":52,"line":103},4,[50,105,106],{"class":63},"  \"testEnvironment\"",[50,108,94],{"class":56},[50,110,111],{"class":70},"\"node\"",[50,113,100],{"class":56},[50,115,117,120,122,125],{"class":52,"line":116},5,[50,118,119],{"class":63},"  \"testRegex\"",[50,121,94],{"class":56},[50,123,124],{"class":70},"\".e2e-spec.ts$\"",[50,126,100],{"class":56},[50,128,130,133],{"class":52,"line":129},6,[50,131,132],{"class":63},"  \"transform\"",[50,134,135],{"class":56},": {\n",[50,137,139,142,144],{"class":52,"line":138},7,[50,140,141],{"class":63},"    \"^.+\\\\.(t|j)s$\"",[50,143,94],{"class":56},[50,145,146],{"class":70},"\"ts-jest\"\n",[50,148,150],{"class":52,"line":149},8,[50,151,152],{"class":56},"  },\n",[50,154,156,159],{"class":52,"line":155},9,[50,157,158],{"class":63},"  \"moduleNameMapper\"",[50,160,135],{"class":56},[50,162,164,167,169],{"class":52,"line":163},10,[50,165,166],{"class":63},"    \"^src\u002F(.*)$\"",[50,168,94],{"class":56},[50,170,171],{"class":70},"\"\u003CrootDir>\u002F..\u002F..\u002F$1\"\n",[50,173,175],{"class":52,"line":174},11,[50,176,177],{"class":56},"  }\n",[50,179,181],{"class":52,"line":180},12,[50,182,183],{"class":56},"}\n",[14,185,186],{},"主な設定項目：",[188,189,190,197,203,209],"ul",{},[191,192,193,196],"li",{},[28,194,195],{},"moduleFileExtensions",": 使用するファイル拡張子",[191,198,199,202],{},[28,200,201],{},"testEnvironment",": テスト実行環境",[191,204,205,208],{},[28,206,207],{},"testRegex",": テストファイルの検出パターン",[191,210,211,214],{},[28,212,213],{},"moduleNameMapper",": パスエイリアスの解決",[14,216,217,218,225],{},"詳細は",[219,220,224],"a",{"href":221,"rel":222},"https:\u002F\u002Fjestjs.io\u002Fja\u002Fdocs\u002Fconfiguration#modulenamemapper-objectstring-string--arraystring",[223],"nofollow","Jest公式ドキュメント","を参照してください。",[10,227,229],{"id":228},"typeorm設定","TypeORM設定",[14,231,232],{},[233,234,235,236,239],"strong",{},"⚠️ 警告：",[28,237,238],{},"synchronize: true","は本番環境で使用しないでください。既存データが失われる可能性があります。",[21,241,245],{"className":242,"code":243,"language":244,"meta":30,"style":30},"language-typescript shiki shiki-themes github-light github-dark","\u002F\u002F ormconfig.test.ts\nmodule.exports = {\n  type: 'mysql',\n  host: process.env.DB_HOST || 'localhost',\n  port: process.env.DB_PORT || '3306',\n  username: process.env.DB_USERNAME || 'test_user',\n  password: process.env.DB_PASSWORD || 'test_password',\n  database: process.env.DB_NAME || 'test_db',\n  \u002F\u002F テスト環境のみ有効化：Entity定義からテーブルを自動生成\n  synchronize: true,\n  \u002F\u002F 実行SQLをログ出力\n  logging: true,\n  entities: ['src\u002Fdomain\u002Fentities\u002F*.ts'],\n  migrations: ['src\u002Fdatabases\u002Fmigrations\u002F*.ts'],\n  seeds: ['src\u002Ftest\u002Fdatabases\u002Fseeders\u002F*.seed.{js,ts}'],\n  subscribers: ['src\u002Fsubscribers\u002F**\u002F*.ts'],\n  cli: {\n    migrationsDir: 'src\u002Fdatabases\u002Fmigrations',\n    entitiesDir: 'src\u002Fdomain\u002Fentities',\n    seedersDir: 'src\u002Fdatabases\u002Fseeders',\n    subscribersDir: 'src\u002Fsubscribers',\n  },\n}\n","typescript",[28,246,247,253,271,281,297,312,327,342,357,362,372,377,386,397,408,419,430,436,447,458,469,480,485],{"__ignoreMap":30},[50,248,249],{"class":52,"line":53},[50,250,252],{"class":251},"sJ8bj","\u002F\u002F ormconfig.test.ts\n",[50,254,255,258,261,264,268],{"class":52,"line":60},[50,256,257],{"class":63},"module",[50,259,260],{"class":56},".",[50,262,263],{"class":63},"exports",[50,265,267],{"class":266},"szBVR"," =",[50,269,270],{"class":56}," {\n",[50,272,273,276,279],{"class":52,"line":88},[50,274,275],{"class":56},"  type: ",[50,277,278],{"class":70},"'mysql'",[50,280,100],{"class":56},[50,282,283,286,289,292,295],{"class":52,"line":103},[50,284,285],{"class":56},"  host: process.env.",[50,287,288],{"class":63},"DB_HOST",[50,290,291],{"class":266}," ||",[50,293,294],{"class":70}," 'localhost'",[50,296,100],{"class":56},[50,298,299,302,305,307,310],{"class":52,"line":116},[50,300,301],{"class":56},"  port: process.env.",[50,303,304],{"class":63},"DB_PORT",[50,306,291],{"class":266},[50,308,309],{"class":70}," '3306'",[50,311,100],{"class":56},[50,313,314,317,320,322,325],{"class":52,"line":129},[50,315,316],{"class":56},"  username: process.env.",[50,318,319],{"class":63},"DB_USERNAME",[50,321,291],{"class":266},[50,323,324],{"class":70}," 'test_user'",[50,326,100],{"class":56},[50,328,329,332,335,337,340],{"class":52,"line":138},[50,330,331],{"class":56},"  password: process.env.",[50,333,334],{"class":63},"DB_PASSWORD",[50,336,291],{"class":266},[50,338,339],{"class":70}," 'test_password'",[50,341,100],{"class":56},[50,343,344,347,350,352,355],{"class":52,"line":149},[50,345,346],{"class":56},"  database: process.env.",[50,348,349],{"class":63},"DB_NAME",[50,351,291],{"class":266},[50,353,354],{"class":70}," 'test_db'",[50,356,100],{"class":56},[50,358,359],{"class":52,"line":155},[50,360,361],{"class":251},"  \u002F\u002F テスト環境のみ有効化：Entity定義からテーブルを自動生成\n",[50,363,364,367,370],{"class":52,"line":163},[50,365,366],{"class":56},"  synchronize: ",[50,368,369],{"class":63},"true",[50,371,100],{"class":56},[50,373,374],{"class":52,"line":174},[50,375,376],{"class":251},"  \u002F\u002F 実行SQLをログ出力\n",[50,378,379,382,384],{"class":52,"line":180},[50,380,381],{"class":56},"  logging: ",[50,383,369],{"class":63},[50,385,100],{"class":56},[50,387,389,392,395],{"class":52,"line":388},13,[50,390,391],{"class":56},"  entities: [",[50,393,394],{"class":70},"'src\u002Fdomain\u002Fentities\u002F*.ts'",[50,396,85],{"class":56},[50,398,400,403,406],{"class":52,"line":399},14,[50,401,402],{"class":56},"  migrations: [",[50,404,405],{"class":70},"'src\u002Fdatabases\u002Fmigrations\u002F*.ts'",[50,407,85],{"class":56},[50,409,411,414,417],{"class":52,"line":410},15,[50,412,413],{"class":56},"  seeds: [",[50,415,416],{"class":70},"'src\u002Ftest\u002Fdatabases\u002Fseeders\u002F*.seed.{js,ts}'",[50,418,85],{"class":56},[50,420,422,425,428],{"class":52,"line":421},16,[50,423,424],{"class":56},"  subscribers: [",[50,426,427],{"class":70},"'src\u002Fsubscribers\u002F**\u002F*.ts'",[50,429,85],{"class":56},[50,431,433],{"class":52,"line":432},17,[50,434,435],{"class":56},"  cli: {\n",[50,437,439,442,445],{"class":52,"line":438},18,[50,440,441],{"class":56},"    migrationsDir: ",[50,443,444],{"class":70},"'src\u002Fdatabases\u002Fmigrations'",[50,446,100],{"class":56},[50,448,450,453,456],{"class":52,"line":449},19,[50,451,452],{"class":56},"    entitiesDir: ",[50,454,455],{"class":70},"'src\u002Fdomain\u002Fentities'",[50,457,100],{"class":56},[50,459,461,464,467],{"class":52,"line":460},20,[50,462,463],{"class":56},"    seedersDir: ",[50,465,466],{"class":70},"'src\u002Fdatabases\u002Fseeders'",[50,468,100],{"class":56},[50,470,472,475,478],{"class":52,"line":471},21,[50,473,474],{"class":56},"    subscribersDir: ",[50,476,477],{"class":70},"'src\u002Fsubscribers'",[50,479,100],{"class":56},[50,481,483],{"class":52,"line":482},22,[50,484,152],{"class":56},[50,486,488],{"class":52,"line":487},23,[50,489,183],{"class":56},[14,491,492,495,496,499],{},[28,493,494],{},"synchronize","オプションは、アプリケーション起動時にEntity定義からテーブルを自動生成する便利な機能ですが、既存のテーブル構造を上書きするため、",[233,497,498],{},"テスト環境専用","としてください。",[14,501,217,502,225],{},[219,503,506],{"href":504,"rel":505},"https:\u002F\u002Fgithub.com\u002Ftypeorm\u002Ftypeorm\u002Fblob\u002Fmaster\u002Fdocs\u002Ffaq.md",[223],"TypeORM FAQ",[10,508,509],{"id":509},"必要なパッケージのインストール",[21,511,515],{"className":512,"code":513,"language":514,"meta":30,"style":30},"language-bash shiki shiki-themes github-light github-dark","npm install --save-dev @nestjs\u002Ftesting\n","bash",[28,516,517],{"__ignoreMap":30},[50,518,519,523,526,529],{"class":52,"line":53},[50,520,522],{"class":521},"sScJk","npm",[50,524,525],{"class":70}," install",[50,527,528],{"class":63}," --save-dev",[50,530,531],{"class":70}," @nestjs\u002Ftesting\n",[14,533,534,535],{},"公式ドキュメント: ",[219,536,539],{"href":537,"rel":538},"https:\u002F\u002Fdocs.nestjs.com\u002Ffundamentals\u002Ftesting",[223],"NestJS Testing",[10,541,543],{"id":542},"テスト対象のapi仕様","テスト対象のAPI仕様",[14,545,546],{},"以下のユーザー情報取得APIをテストします。",[36,548,549],{"id":549},"リクエスト例",[21,551,554],{"className":552,"code":553,"language":26},[24],"GET http:\u002F\u002Flocalhost:3000\u002Fusers?name=テスト\nAuthorization: Bearer \u003Ctoken>\n",[28,555,553],{"__ignoreMap":30},[36,557,558],{"id":558},"レスポンス例",[21,560,562],{"className":44,"code":561,"language":46,"meta":30,"style":30},"{\n  \"statusCode\": 200,\n  \"message\": \"SUCCESS\",\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"テスト\",\n      \"ins_ts\": \"2021\u002F11\u002F29 13:47\"\n    }\n  ]\n}\n",[28,563,564,568,580,592,600,605,617,629,639,644,649],{"__ignoreMap":30},[50,565,566],{"class":52,"line":53},[50,567,57],{"class":56},[50,569,570,573,575,578],{"class":52,"line":60},[50,571,572],{"class":63},"  \"statusCode\"",[50,574,94],{"class":56},[50,576,577],{"class":63},"200",[50,579,100],{"class":56},[50,581,582,585,587,590],{"class":52,"line":88},[50,583,584],{"class":63},"  \"message\"",[50,586,94],{"class":56},[50,588,589],{"class":70},"\"SUCCESS\"",[50,591,100],{"class":56},[50,593,594,597],{"class":52,"line":103},[50,595,596],{"class":63},"  \"data\"",[50,598,599],{"class":56},": [\n",[50,601,602],{"class":52,"line":116},[50,603,604],{"class":56},"    {\n",[50,606,607,610,612,615],{"class":52,"line":129},[50,608,609],{"class":63},"      \"id\"",[50,611,94],{"class":56},[50,613,614],{"class":63},"1",[50,616,100],{"class":56},[50,618,619,622,624,627],{"class":52,"line":138},[50,620,621],{"class":63},"      \"name\"",[50,623,94],{"class":56},[50,625,626],{"class":70},"\"テスト\"",[50,628,100],{"class":56},[50,630,631,634,636],{"class":52,"line":149},[50,632,633],{"class":63},"      \"ins_ts\"",[50,635,94],{"class":56},[50,637,638],{"class":70},"\"2021\u002F11\u002F29 13:47\"\n",[50,640,641],{"class":52,"line":155},[50,642,643],{"class":56},"    }\n",[50,645,646],{"class":52,"line":163},[50,647,648],{"class":56},"  ]\n",[50,650,651],{"class":52,"line":174},[50,652,183],{"class":56},[10,654,656],{"id":655},"e2eテストコード","E2Eテストコード",[36,658,659],{"id":659},"テストモジュールのセットアップ",[21,661,663],{"className":242,"code":662,"language":244,"meta":30,"style":30},"import { INestApplication, ValidationPipe } from '@nestjs\u002Fcommon'\nimport { ConfigModule } from '@nestjs\u002Fconfig'\nimport { APP_GUARD } from '@nestjs\u002Fcore'\nimport { Test, TestingModule } from '@nestjs\u002Ftesting'\nimport { TypeOrmModule } from '@nestjs\u002Ftypeorm'\nimport * as request from 'supertest'\n\ndescribe('ユーザーAPI (E2E)', () => {\n  let app: INestApplication\n\n  \u002F\u002F 各テスト実行前にデータをリセット\n  beforeEach(async () => {\n    await useRefreshDatabase()\n    await runTestDataSeeder()\n  })\n\n  \u002F\u002F テスト開始前に1回だけ実行\n  beforeAll(async () => {\n    const moduleFixture: TestingModule = await Test.createTestingModule({\n      imports: [\n        TypeOrmModule.forFeature([User]),\n        ConfigModule.forRoot({\n          envFilePath: ENV_FILE_PATH,\n        }),\n        AppModule,\n      ],\n      controllers: [UserController],\n      providers: [\n        UserService,\n        {\n          provide: APP_GUARD,\n          useExisting: RoleGuard,\n        },\n        RoleGuard,\n      ],\n    }).compile()\n\n    app = moduleFixture.createNestApplication()\n    app.useGlobalPipes(new ValidationPipe())\n    await app.init()\n  })\n\n  \u002F\u002F テスト終了後にクリーンアップ\n  afterAll(async () => {\n    await app.close()\n    await tearDownDatabase()\n  })\n\n  \u002F\u002F ... テストケース\n})\n",[28,664,665,679,691,703,715,727,745,751,770,784,788,793,810,821,830,835,839,844,859,886,891,902,912,922,928,934,940,946,952,958,964,975,981,987,993,998,1009,1014,1031,1051,1064,1069,1074,1080,1096,1108,1118,1123,1128,1134],{"__ignoreMap":30},[50,666,667,670,673,676],{"class":52,"line":53},[50,668,669],{"class":266},"import",[50,671,672],{"class":56}," { INestApplication, ValidationPipe } ",[50,674,675],{"class":266},"from",[50,677,678],{"class":70}," '@nestjs\u002Fcommon'\n",[50,680,681,683,686,688],{"class":52,"line":60},[50,682,669],{"class":266},[50,684,685],{"class":56}," { ConfigModule } ",[50,687,675],{"class":266},[50,689,690],{"class":70}," '@nestjs\u002Fconfig'\n",[50,692,693,695,698,700],{"class":52,"line":88},[50,694,669],{"class":266},[50,696,697],{"class":56}," { APP_GUARD } ",[50,699,675],{"class":266},[50,701,702],{"class":70}," '@nestjs\u002Fcore'\n",[50,704,705,707,710,712],{"class":52,"line":103},[50,706,669],{"class":266},[50,708,709],{"class":56}," { Test, TestingModule } ",[50,711,675],{"class":266},[50,713,714],{"class":70}," '@nestjs\u002Ftesting'\n",[50,716,717,719,722,724],{"class":52,"line":116},[50,718,669],{"class":266},[50,720,721],{"class":56}," { TypeOrmModule } ",[50,723,675],{"class":266},[50,725,726],{"class":70}," '@nestjs\u002Ftypeorm'\n",[50,728,729,731,734,737,740,742],{"class":52,"line":129},[50,730,669],{"class":266},[50,732,733],{"class":63}," *",[50,735,736],{"class":266}," as",[50,738,739],{"class":56}," request ",[50,741,675],{"class":266},[50,743,744],{"class":70}," 'supertest'\n",[50,746,747],{"class":52,"line":138},[50,748,750],{"emptyLinePlaceholder":749},true,"\n",[50,752,753,756,759,762,765,768],{"class":52,"line":149},[50,754,755],{"class":521},"describe",[50,757,758],{"class":56},"(",[50,760,761],{"class":70},"'ユーザーAPI (E2E)'",[50,763,764],{"class":56},", () ",[50,766,767],{"class":266},"=>",[50,769,270],{"class":56},[50,771,772,775,778,781],{"class":52,"line":155},[50,773,774],{"class":266},"  let",[50,776,777],{"class":56}," app",[50,779,780],{"class":266},":",[50,782,783],{"class":521}," INestApplication\n",[50,785,786],{"class":52,"line":163},[50,787,750],{"emptyLinePlaceholder":749},[50,789,790],{"class":52,"line":174},[50,791,792],{"class":251},"  \u002F\u002F 各テスト実行前にデータをリセット\n",[50,794,795,798,800,803,806,808],{"class":52,"line":180},[50,796,797],{"class":521},"  beforeEach",[50,799,758],{"class":56},[50,801,802],{"class":266},"async",[50,804,805],{"class":56}," () ",[50,807,767],{"class":266},[50,809,270],{"class":56},[50,811,812,815,818],{"class":52,"line":388},[50,813,814],{"class":266},"    await",[50,816,817],{"class":521}," useRefreshDatabase",[50,819,820],{"class":56},"()\n",[50,822,823,825,828],{"class":52,"line":399},[50,824,814],{"class":266},[50,826,827],{"class":521}," runTestDataSeeder",[50,829,820],{"class":56},[50,831,832],{"class":52,"line":410},[50,833,834],{"class":56},"  })\n",[50,836,837],{"class":52,"line":421},[50,838,750],{"emptyLinePlaceholder":749},[50,840,841],{"class":52,"line":432},[50,842,843],{"class":251},"  \u002F\u002F テスト開始前に1回だけ実行\n",[50,845,846,849,851,853,855,857],{"class":52,"line":438},[50,847,848],{"class":521},"  beforeAll",[50,850,758],{"class":56},[50,852,802],{"class":266},[50,854,805],{"class":56},[50,856,767],{"class":266},[50,858,270],{"class":56},[50,860,861,864,867,869,872,874,877,880,883],{"class":52,"line":449},[50,862,863],{"class":266},"    const",[50,865,866],{"class":63}," moduleFixture",[50,868,780],{"class":266},[50,870,871],{"class":521}," TestingModule",[50,873,267],{"class":266},[50,875,876],{"class":266}," await",[50,878,879],{"class":56}," Test.",[50,881,882],{"class":521},"createTestingModule",[50,884,885],{"class":56},"({\n",[50,887,888],{"class":52,"line":460},[50,889,890],{"class":56},"      imports: [\n",[50,892,893,896,899],{"class":52,"line":471},[50,894,895],{"class":56},"        TypeOrmModule.",[50,897,898],{"class":521},"forFeature",[50,900,901],{"class":56},"([User]),\n",[50,903,904,907,910],{"class":52,"line":482},[50,905,906],{"class":56},"        ConfigModule.",[50,908,909],{"class":521},"forRoot",[50,911,885],{"class":56},[50,913,914,917,920],{"class":52,"line":487},[50,915,916],{"class":56},"          envFilePath: ",[50,918,919],{"class":63},"ENV_FILE_PATH",[50,921,100],{"class":56},[50,923,925],{"class":52,"line":924},24,[50,926,927],{"class":56},"        }),\n",[50,929,931],{"class":52,"line":930},25,[50,932,933],{"class":56},"        AppModule,\n",[50,935,937],{"class":52,"line":936},26,[50,938,939],{"class":56},"      ],\n",[50,941,943],{"class":52,"line":942},27,[50,944,945],{"class":56},"      controllers: [UserController],\n",[50,947,949],{"class":52,"line":948},28,[50,950,951],{"class":56},"      providers: [\n",[50,953,955],{"class":52,"line":954},29,[50,956,957],{"class":56},"        UserService,\n",[50,959,961],{"class":52,"line":960},30,[50,962,963],{"class":56},"        {\n",[50,965,967,970,973],{"class":52,"line":966},31,[50,968,969],{"class":56},"          provide: ",[50,971,972],{"class":63},"APP_GUARD",[50,974,100],{"class":56},[50,976,978],{"class":52,"line":977},32,[50,979,980],{"class":56},"          useExisting: RoleGuard,\n",[50,982,984],{"class":52,"line":983},33,[50,985,986],{"class":56},"        },\n",[50,988,990],{"class":52,"line":989},34,[50,991,992],{"class":56},"        RoleGuard,\n",[50,994,996],{"class":52,"line":995},35,[50,997,939],{"class":56},[50,999,1001,1004,1007],{"class":52,"line":1000},36,[50,1002,1003],{"class":56},"    }).",[50,1005,1006],{"class":521},"compile",[50,1008,820],{"class":56},[50,1010,1012],{"class":52,"line":1011},37,[50,1013,750],{"emptyLinePlaceholder":749},[50,1015,1017,1020,1023,1026,1029],{"class":52,"line":1016},38,[50,1018,1019],{"class":56},"    app ",[50,1021,1022],{"class":266},"=",[50,1024,1025],{"class":56}," moduleFixture.",[50,1027,1028],{"class":521},"createNestApplication",[50,1030,820],{"class":56},[50,1032,1034,1037,1040,1042,1045,1048],{"class":52,"line":1033},39,[50,1035,1036],{"class":56},"    app.",[50,1038,1039],{"class":521},"useGlobalPipes",[50,1041,758],{"class":56},[50,1043,1044],{"class":266},"new",[50,1046,1047],{"class":521}," ValidationPipe",[50,1049,1050],{"class":56},"())\n",[50,1052,1054,1056,1059,1062],{"class":52,"line":1053},40,[50,1055,814],{"class":266},[50,1057,1058],{"class":56}," app.",[50,1060,1061],{"class":521},"init",[50,1063,820],{"class":56},[50,1065,1067],{"class":52,"line":1066},41,[50,1068,834],{"class":56},[50,1070,1072],{"class":52,"line":1071},42,[50,1073,750],{"emptyLinePlaceholder":749},[50,1075,1077],{"class":52,"line":1076},43,[50,1078,1079],{"class":251},"  \u002F\u002F テスト終了後にクリーンアップ\n",[50,1081,1083,1086,1088,1090,1092,1094],{"class":52,"line":1082},44,[50,1084,1085],{"class":521},"  afterAll",[50,1087,758],{"class":56},[50,1089,802],{"class":266},[50,1091,805],{"class":56},[50,1093,767],{"class":266},[50,1095,270],{"class":56},[50,1097,1099,1101,1103,1106],{"class":52,"line":1098},45,[50,1100,814],{"class":266},[50,1102,1058],{"class":56},[50,1104,1105],{"class":521},"close",[50,1107,820],{"class":56},[50,1109,1111,1113,1116],{"class":52,"line":1110},46,[50,1112,814],{"class":266},[50,1114,1115],{"class":521}," tearDownDatabase",[50,1117,820],{"class":56},[50,1119,1121],{"class":52,"line":1120},47,[50,1122,834],{"class":56},[50,1124,1126],{"class":52,"line":1125},48,[50,1127,750],{"emptyLinePlaceholder":749},[50,1129,1131],{"class":52,"line":1130},49,[50,1132,1133],{"class":251},"  \u002F\u002F ... テストケース\n",[50,1135,1137],{"class":52,"line":1136},50,[50,1138,1139],{"class":56},"})\n",[36,1141,1142],{"id":1142},"ヘルパー関数",[21,1144,1146],{"className":242,"code":1145,"language":244,"meta":30,"style":30},"\u002F**\n * ユーザー一覧を取得\n *\u002F\nconst index = async (account?: E2eLoginData): Promise\u003Crequest.Response> => {\n  const req = request(app.getHttpServer()).get(API_END_POINTS.USER)\n\n  if (account) {\n    req.set('Authorization', `Bearer ${await getJwtToken(request, app, account)}`)\n  }\n\n  return await req\n}\n\n\u002F**\n * ユーザーを取得\n *\u002F\nconst show = async (\n  id: number,\n  account?: E2eLoginData\n): Promise\u003Crequest.Response> => {\n  const req = request(app.getHttpServer()).get(`${API_END_POINTS.USER}\u002F${id}`)\n\n  if (account) {\n    req.set('Authorization', `Bearer ${await getJwtToken(request, app, account)}`)\n  }\n\n  return await req\n}\n\n\u002F**\n * ユーザーを作成\n *\u002F\nconst create = async (\n  dto: CreateUserDto,\n  account?: E2eLoginData\n): Promise\u003Crequest.Response> => {\n  const req = request(app.getHttpServer())\n    .post(API_END_POINTS.USER)\n    .set('Accept', 'application\u002Fjson')\n    .send(dto)\n\n  if (account) {\n    req.set('Authorization', `Bearer ${await getJwtToken(request, app, account)}`)\n  }\n\n  return await req\n}\n",[28,1147,1148,1153,1158,1163,1215,1253,1257,1265,1309,1313,1317,1327,1331,1335,1339,1344,1348,1362,1374,1384,1406,1445,1449,1455,1491,1495,1499,1507,1511,1515,1519,1524,1528,1541,1553,1561,1583,1599,1617,1635,1645,1649,1655,1691,1695,1699,1707],{"__ignoreMap":30},[50,1149,1150],{"class":52,"line":53},[50,1151,1152],{"class":251},"\u002F**\n",[50,1154,1155],{"class":52,"line":60},[50,1156,1157],{"class":251}," * ユーザー一覧を取得\n",[50,1159,1160],{"class":52,"line":88},[50,1161,1162],{"class":251}," *\u002F\n",[50,1164,1165,1168,1171,1173,1176,1179,1183,1186,1189,1192,1194,1197,1200,1203,1205,1208,1211,1213],{"class":52,"line":103},[50,1166,1167],{"class":266},"const",[50,1169,1170],{"class":521}," index",[50,1172,267],{"class":266},[50,1174,1175],{"class":266}," async",[50,1177,1178],{"class":56}," (",[50,1180,1182],{"class":1181},"s4XuR","account",[50,1184,1185],{"class":266},"?:",[50,1187,1188],{"class":521}," E2eLoginData",[50,1190,1191],{"class":56},")",[50,1193,780],{"class":266},[50,1195,1196],{"class":521}," Promise",[50,1198,1199],{"class":56},"\u003C",[50,1201,1202],{"class":521},"request",[50,1204,260],{"class":56},[50,1206,1207],{"class":521},"Response",[50,1209,1210],{"class":56},"> ",[50,1212,767],{"class":266},[50,1214,270],{"class":56},[50,1216,1217,1220,1223,1225,1228,1231,1234,1237,1240,1242,1245,1247,1250],{"class":52,"line":116},[50,1218,1219],{"class":266},"  const",[50,1221,1222],{"class":63}," req",[50,1224,267],{"class":266},[50,1226,1227],{"class":521}," request",[50,1229,1230],{"class":56},"(app.",[50,1232,1233],{"class":521},"getHttpServer",[50,1235,1236],{"class":56},"()).",[50,1238,1239],{"class":521},"get",[50,1241,758],{"class":56},[50,1243,1244],{"class":63},"API_END_POINTS",[50,1246,260],{"class":56},[50,1248,1249],{"class":63},"USER",[50,1251,1252],{"class":56},")\n",[50,1254,1255],{"class":52,"line":129},[50,1256,750],{"emptyLinePlaceholder":749},[50,1258,1259,1262],{"class":52,"line":138},[50,1260,1261],{"class":266},"  if",[50,1263,1264],{"class":56}," (account) {\n",[50,1266,1267,1270,1273,1275,1278,1280,1283,1286,1289,1291,1293,1295,1298,1300,1302,1304,1307],{"class":52,"line":149},[50,1268,1269],{"class":56},"    req.",[50,1271,1272],{"class":521},"set",[50,1274,758],{"class":56},[50,1276,1277],{"class":70},"'Authorization'",[50,1279,74],{"class":56},[50,1281,1282],{"class":70},"`Bearer ${",[50,1284,1285],{"class":266},"await",[50,1287,1288],{"class":521}," getJwtToken",[50,1290,758],{"class":70},[50,1292,1202],{"class":56},[50,1294,74],{"class":70},[50,1296,1297],{"class":56},"app",[50,1299,74],{"class":70},[50,1301,1182],{"class":56},[50,1303,1191],{"class":70},[50,1305,1306],{"class":70},"}`",[50,1308,1252],{"class":56},[50,1310,1311],{"class":52,"line":155},[50,1312,177],{"class":56},[50,1314,1315],{"class":52,"line":163},[50,1316,750],{"emptyLinePlaceholder":749},[50,1318,1319,1322,1324],{"class":52,"line":174},[50,1320,1321],{"class":266},"  return",[50,1323,876],{"class":266},[50,1325,1326],{"class":56}," req\n",[50,1328,1329],{"class":52,"line":180},[50,1330,183],{"class":56},[50,1332,1333],{"class":52,"line":388},[50,1334,750],{"emptyLinePlaceholder":749},[50,1336,1337],{"class":52,"line":399},[50,1338,1152],{"class":251},[50,1340,1341],{"class":52,"line":410},[50,1342,1343],{"class":251}," * ユーザーを取得\n",[50,1345,1346],{"class":52,"line":421},[50,1347,1162],{"class":251},[50,1349,1350,1352,1355,1357,1359],{"class":52,"line":432},[50,1351,1167],{"class":266},[50,1353,1354],{"class":521}," show",[50,1356,267],{"class":266},[50,1358,1175],{"class":266},[50,1360,1361],{"class":56}," (\n",[50,1363,1364,1367,1369,1372],{"class":52,"line":438},[50,1365,1366],{"class":1181},"  id",[50,1368,780],{"class":266},[50,1370,1371],{"class":63}," number",[50,1373,100],{"class":56},[50,1375,1376,1379,1381],{"class":52,"line":449},[50,1377,1378],{"class":1181},"  account",[50,1380,1185],{"class":266},[50,1382,1383],{"class":521}," E2eLoginData\n",[50,1385,1386,1388,1390,1392,1394,1396,1398,1400,1402,1404],{"class":52,"line":460},[50,1387,1191],{"class":56},[50,1389,780],{"class":266},[50,1391,1196],{"class":521},[50,1393,1199],{"class":56},[50,1395,1202],{"class":521},[50,1397,260],{"class":56},[50,1399,1207],{"class":521},[50,1401,1210],{"class":56},[50,1403,767],{"class":266},[50,1405,270],{"class":56},[50,1407,1408,1410,1412,1414,1416,1418,1420,1422,1424,1426,1429,1431,1433,1435,1438,1441,1443],{"class":52,"line":471},[50,1409,1219],{"class":266},[50,1411,1222],{"class":63},[50,1413,267],{"class":266},[50,1415,1227],{"class":521},[50,1417,1230],{"class":56},[50,1419,1233],{"class":521},[50,1421,1236],{"class":56},[50,1423,1239],{"class":521},[50,1425,758],{"class":56},[50,1427,1428],{"class":70},"`${",[50,1430,1244],{"class":63},[50,1432,260],{"class":70},[50,1434,1249],{"class":63},[50,1436,1437],{"class":70},"}\u002F${",[50,1439,1440],{"class":56},"id",[50,1442,1306],{"class":70},[50,1444,1252],{"class":56},[50,1446,1447],{"class":52,"line":482},[50,1448,750],{"emptyLinePlaceholder":749},[50,1450,1451,1453],{"class":52,"line":487},[50,1452,1261],{"class":266},[50,1454,1264],{"class":56},[50,1456,1457,1459,1461,1463,1465,1467,1469,1471,1473,1475,1477,1479,1481,1483,1485,1487,1489],{"class":52,"line":924},[50,1458,1269],{"class":56},[50,1460,1272],{"class":521},[50,1462,758],{"class":56},[50,1464,1277],{"class":70},[50,1466,74],{"class":56},[50,1468,1282],{"class":70},[50,1470,1285],{"class":266},[50,1472,1288],{"class":521},[50,1474,758],{"class":70},[50,1476,1202],{"class":56},[50,1478,74],{"class":70},[50,1480,1297],{"class":56},[50,1482,74],{"class":70},[50,1484,1182],{"class":56},[50,1486,1191],{"class":70},[50,1488,1306],{"class":70},[50,1490,1252],{"class":56},[50,1492,1493],{"class":52,"line":930},[50,1494,177],{"class":56},[50,1496,1497],{"class":52,"line":936},[50,1498,750],{"emptyLinePlaceholder":749},[50,1500,1501,1503,1505],{"class":52,"line":942},[50,1502,1321],{"class":266},[50,1504,876],{"class":266},[50,1506,1326],{"class":56},[50,1508,1509],{"class":52,"line":948},[50,1510,183],{"class":56},[50,1512,1513],{"class":52,"line":954},[50,1514,750],{"emptyLinePlaceholder":749},[50,1516,1517],{"class":52,"line":960},[50,1518,1152],{"class":251},[50,1520,1521],{"class":52,"line":966},[50,1522,1523],{"class":251}," * ユーザーを作成\n",[50,1525,1526],{"class":52,"line":977},[50,1527,1162],{"class":251},[50,1529,1530,1532,1535,1537,1539],{"class":52,"line":983},[50,1531,1167],{"class":266},[50,1533,1534],{"class":521}," create",[50,1536,267],{"class":266},[50,1538,1175],{"class":266},[50,1540,1361],{"class":56},[50,1542,1543,1546,1548,1551],{"class":52,"line":989},[50,1544,1545],{"class":1181},"  dto",[50,1547,780],{"class":266},[50,1549,1550],{"class":521}," CreateUserDto",[50,1552,100],{"class":56},[50,1554,1555,1557,1559],{"class":52,"line":995},[50,1556,1378],{"class":1181},[50,1558,1185],{"class":266},[50,1560,1383],{"class":521},[50,1562,1563,1565,1567,1569,1571,1573,1575,1577,1579,1581],{"class":52,"line":1000},[50,1564,1191],{"class":56},[50,1566,780],{"class":266},[50,1568,1196],{"class":521},[50,1570,1199],{"class":56},[50,1572,1202],{"class":521},[50,1574,260],{"class":56},[50,1576,1207],{"class":521},[50,1578,1210],{"class":56},[50,1580,767],{"class":266},[50,1582,270],{"class":56},[50,1584,1585,1587,1589,1591,1593,1595,1597],{"class":52,"line":1011},[50,1586,1219],{"class":266},[50,1588,1222],{"class":63},[50,1590,267],{"class":266},[50,1592,1227],{"class":521},[50,1594,1230],{"class":56},[50,1596,1233],{"class":521},[50,1598,1050],{"class":56},[50,1600,1601,1604,1607,1609,1611,1613,1615],{"class":52,"line":1016},[50,1602,1603],{"class":56},"    .",[50,1605,1606],{"class":521},"post",[50,1608,758],{"class":56},[50,1610,1244],{"class":63},[50,1612,260],{"class":56},[50,1614,1249],{"class":63},[50,1616,1252],{"class":56},[50,1618,1619,1621,1623,1625,1628,1630,1633],{"class":52,"line":1033},[50,1620,1603],{"class":56},[50,1622,1272],{"class":521},[50,1624,758],{"class":56},[50,1626,1627],{"class":70},"'Accept'",[50,1629,74],{"class":56},[50,1631,1632],{"class":70},"'application\u002Fjson'",[50,1634,1252],{"class":56},[50,1636,1637,1639,1642],{"class":52,"line":1053},[50,1638,1603],{"class":56},[50,1640,1641],{"class":521},"send",[50,1643,1644],{"class":56},"(dto)\n",[50,1646,1647],{"class":52,"line":1066},[50,1648,750],{"emptyLinePlaceholder":749},[50,1650,1651,1653],{"class":52,"line":1071},[50,1652,1261],{"class":266},[50,1654,1264],{"class":56},[50,1656,1657,1659,1661,1663,1665,1667,1669,1671,1673,1675,1677,1679,1681,1683,1685,1687,1689],{"class":52,"line":1076},[50,1658,1269],{"class":56},[50,1660,1272],{"class":521},[50,1662,758],{"class":56},[50,1664,1277],{"class":70},[50,1666,74],{"class":56},[50,1668,1282],{"class":70},[50,1670,1285],{"class":266},[50,1672,1288],{"class":521},[50,1674,758],{"class":70},[50,1676,1202],{"class":56},[50,1678,74],{"class":70},[50,1680,1297],{"class":56},[50,1682,74],{"class":70},[50,1684,1182],{"class":56},[50,1686,1191],{"class":70},[50,1688,1306],{"class":70},[50,1690,1252],{"class":56},[50,1692,1693],{"class":52,"line":1082},[50,1694,177],{"class":56},[50,1696,1697],{"class":52,"line":1098},[50,1698,750],{"emptyLinePlaceholder":749},[50,1700,1701,1703,1705],{"class":52,"line":1110},[50,1702,1321],{"class":266},[50,1704,876],{"class":266},[50,1706,1326],{"class":56},[50,1708,1709],{"class":52,"line":1120},[50,1710,183],{"class":56},[36,1712,1713],{"id":1713},"テストケース",[21,1715,1717],{"className":242,"code":1716,"language":244,"meta":30,"style":30},"describe('ユーザー一覧取得', () => {\n  it('認証済みユーザーがユーザー一覧を取得できる', async () => {\n    const res = await index(LOGIN_DATA.SERVICE_ADMIN)\n\n    expect(res.status).toEqual(HTTP_STATUS_CODES.OK)\n    expect(res.body).toEqual(INDEX_USERS)\n  })\n})\n\ndescribe('ユーザー詳細取得', () => {\n  it('認証済みユーザーがユーザー詳細を取得できる', async () => {\n    const users = (await index(LOGIN_DATA.SERVICE_ADMIN)).body\n    const id = users[0].id\n\n    const res = await show(id, LOGIN_DATA.SERVICE_ADMIN)\n\n    expect(res.status).toEqual(HTTP_STATUS_CODES.OK)\n    expect(res.body).toEqual(SHOW_USER_DATA)\n  })\n})\n\ndescribe('ユーザー作成', () => {\n  it('認証済みユーザーがユーザーを作成できる', async () => {\n    const body: CreateUserDto = {\n      name: '新規ユーザー',\n      password: 'password',\n      password_confirm: 'password',\n    }\n\n    const res = await create(body, LOGIN_DATA.SERVICE_ADMIN)\n\n    expect(res.status).toEqual(HTTP_STATUS_CODES.CREATED)\n    expect(res.body.message).toEqual(RESPONSE_MESSAGES.USER_CREATED)\n  })\n})\n",[28,1718,1719,1734,1754,1779,1783,1806,1822,1826,1830,1834,1849,1868,1894,1912,1916,1939,1943,1961,1976,1980,1984,1988,2003,2022,2037,2047,2057,2066,2070,2074,2097,2101,2120,2141,2145],{"__ignoreMap":30},[50,1720,1721,1723,1725,1728,1730,1732],{"class":52,"line":53},[50,1722,755],{"class":521},[50,1724,758],{"class":56},[50,1726,1727],{"class":70},"'ユーザー一覧取得'",[50,1729,764],{"class":56},[50,1731,767],{"class":266},[50,1733,270],{"class":56},[50,1735,1736,1739,1741,1744,1746,1748,1750,1752],{"class":52,"line":60},[50,1737,1738],{"class":521},"  it",[50,1740,758],{"class":56},[50,1742,1743],{"class":70},"'認証済みユーザーがユーザー一覧を取得できる'",[50,1745,74],{"class":56},[50,1747,802],{"class":266},[50,1749,805],{"class":56},[50,1751,767],{"class":266},[50,1753,270],{"class":56},[50,1755,1756,1758,1761,1763,1765,1767,1769,1772,1774,1777],{"class":52,"line":88},[50,1757,863],{"class":266},[50,1759,1760],{"class":63}," res",[50,1762,267],{"class":266},[50,1764,876],{"class":266},[50,1766,1170],{"class":521},[50,1768,758],{"class":56},[50,1770,1771],{"class":63},"LOGIN_DATA",[50,1773,260],{"class":56},[50,1775,1776],{"class":63},"SERVICE_ADMIN",[50,1778,1252],{"class":56},[50,1780,1781],{"class":52,"line":103},[50,1782,750],{"emptyLinePlaceholder":749},[50,1784,1785,1788,1791,1794,1796,1799,1801,1804],{"class":52,"line":116},[50,1786,1787],{"class":521},"    expect",[50,1789,1790],{"class":56},"(res.status).",[50,1792,1793],{"class":521},"toEqual",[50,1795,758],{"class":56},[50,1797,1798],{"class":63},"HTTP_STATUS_CODES",[50,1800,260],{"class":56},[50,1802,1803],{"class":63},"OK",[50,1805,1252],{"class":56},[50,1807,1808,1810,1813,1815,1817,1820],{"class":52,"line":129},[50,1809,1787],{"class":521},[50,1811,1812],{"class":56},"(res.body).",[50,1814,1793],{"class":521},[50,1816,758],{"class":56},[50,1818,1819],{"class":63},"INDEX_USERS",[50,1821,1252],{"class":56},[50,1823,1824],{"class":52,"line":138},[50,1825,834],{"class":56},[50,1827,1828],{"class":52,"line":149},[50,1829,1139],{"class":56},[50,1831,1832],{"class":52,"line":155},[50,1833,750],{"emptyLinePlaceholder":749},[50,1835,1836,1838,1840,1843,1845,1847],{"class":52,"line":163},[50,1837,755],{"class":521},[50,1839,758],{"class":56},[50,1841,1842],{"class":70},"'ユーザー詳細取得'",[50,1844,764],{"class":56},[50,1846,767],{"class":266},[50,1848,270],{"class":56},[50,1850,1851,1853,1855,1858,1860,1862,1864,1866],{"class":52,"line":174},[50,1852,1738],{"class":521},[50,1854,758],{"class":56},[50,1856,1857],{"class":70},"'認証済みユーザーがユーザー詳細を取得できる'",[50,1859,74],{"class":56},[50,1861,802],{"class":266},[50,1863,805],{"class":56},[50,1865,767],{"class":266},[50,1867,270],{"class":56},[50,1869,1870,1872,1875,1877,1879,1881,1883,1885,1887,1889,1891],{"class":52,"line":180},[50,1871,863],{"class":266},[50,1873,1874],{"class":63}," users",[50,1876,267],{"class":266},[50,1878,1178],{"class":56},[50,1880,1285],{"class":266},[50,1882,1170],{"class":521},[50,1884,758],{"class":56},[50,1886,1771],{"class":63},[50,1888,260],{"class":56},[50,1890,1776],{"class":63},[50,1892,1893],{"class":56},")).body\n",[50,1895,1896,1898,1901,1903,1906,1909],{"class":52,"line":388},[50,1897,863],{"class":266},[50,1899,1900],{"class":63}," id",[50,1902,267],{"class":266},[50,1904,1905],{"class":56}," users[",[50,1907,1908],{"class":63},"0",[50,1910,1911],{"class":56},"].id\n",[50,1913,1914],{"class":52,"line":399},[50,1915,750],{"emptyLinePlaceholder":749},[50,1917,1918,1920,1922,1924,1926,1928,1931,1933,1935,1937],{"class":52,"line":410},[50,1919,863],{"class":266},[50,1921,1760],{"class":63},[50,1923,267],{"class":266},[50,1925,876],{"class":266},[50,1927,1354],{"class":521},[50,1929,1930],{"class":56},"(id, ",[50,1932,1771],{"class":63},[50,1934,260],{"class":56},[50,1936,1776],{"class":63},[50,1938,1252],{"class":56},[50,1940,1941],{"class":52,"line":421},[50,1942,750],{"emptyLinePlaceholder":749},[50,1944,1945,1947,1949,1951,1953,1955,1957,1959],{"class":52,"line":432},[50,1946,1787],{"class":521},[50,1948,1790],{"class":56},[50,1950,1793],{"class":521},[50,1952,758],{"class":56},[50,1954,1798],{"class":63},[50,1956,260],{"class":56},[50,1958,1803],{"class":63},[50,1960,1252],{"class":56},[50,1962,1963,1965,1967,1969,1971,1974],{"class":52,"line":438},[50,1964,1787],{"class":521},[50,1966,1812],{"class":56},[50,1968,1793],{"class":521},[50,1970,758],{"class":56},[50,1972,1973],{"class":63},"SHOW_USER_DATA",[50,1975,1252],{"class":56},[50,1977,1978],{"class":52,"line":449},[50,1979,834],{"class":56},[50,1981,1982],{"class":52,"line":460},[50,1983,1139],{"class":56},[50,1985,1986],{"class":52,"line":471},[50,1987,750],{"emptyLinePlaceholder":749},[50,1989,1990,1992,1994,1997,1999,2001],{"class":52,"line":482},[50,1991,755],{"class":521},[50,1993,758],{"class":56},[50,1995,1996],{"class":70},"'ユーザー作成'",[50,1998,764],{"class":56},[50,2000,767],{"class":266},[50,2002,270],{"class":56},[50,2004,2005,2007,2009,2012,2014,2016,2018,2020],{"class":52,"line":487},[50,2006,1738],{"class":521},[50,2008,758],{"class":56},[50,2010,2011],{"class":70},"'認証済みユーザーがユーザーを作成できる'",[50,2013,74],{"class":56},[50,2015,802],{"class":266},[50,2017,805],{"class":56},[50,2019,767],{"class":266},[50,2021,270],{"class":56},[50,2023,2024,2026,2029,2031,2033,2035],{"class":52,"line":924},[50,2025,863],{"class":266},[50,2027,2028],{"class":63}," body",[50,2030,780],{"class":266},[50,2032,1550],{"class":521},[50,2034,267],{"class":266},[50,2036,270],{"class":56},[50,2038,2039,2042,2045],{"class":52,"line":930},[50,2040,2041],{"class":56},"      name: ",[50,2043,2044],{"class":70},"'新規ユーザー'",[50,2046,100],{"class":56},[50,2048,2049,2052,2055],{"class":52,"line":936},[50,2050,2051],{"class":56},"      password: ",[50,2053,2054],{"class":70},"'password'",[50,2056,100],{"class":56},[50,2058,2059,2062,2064],{"class":52,"line":942},[50,2060,2061],{"class":56},"      password_confirm: ",[50,2063,2054],{"class":70},[50,2065,100],{"class":56},[50,2067,2068],{"class":52,"line":948},[50,2069,643],{"class":56},[50,2071,2072],{"class":52,"line":954},[50,2073,750],{"emptyLinePlaceholder":749},[50,2075,2076,2078,2080,2082,2084,2086,2089,2091,2093,2095],{"class":52,"line":960},[50,2077,863],{"class":266},[50,2079,1760],{"class":63},[50,2081,267],{"class":266},[50,2083,876],{"class":266},[50,2085,1534],{"class":521},[50,2087,2088],{"class":56},"(body, ",[50,2090,1771],{"class":63},[50,2092,260],{"class":56},[50,2094,1776],{"class":63},[50,2096,1252],{"class":56},[50,2098,2099],{"class":52,"line":966},[50,2100,750],{"emptyLinePlaceholder":749},[50,2102,2103,2105,2107,2109,2111,2113,2115,2118],{"class":52,"line":977},[50,2104,1787],{"class":521},[50,2106,1790],{"class":56},[50,2108,1793],{"class":521},[50,2110,758],{"class":56},[50,2112,1798],{"class":63},[50,2114,260],{"class":56},[50,2116,2117],{"class":63},"CREATED",[50,2119,1252],{"class":56},[50,2121,2122,2124,2127,2129,2131,2134,2136,2139],{"class":52,"line":983},[50,2123,1787],{"class":521},[50,2125,2126],{"class":56},"(res.body.message).",[50,2128,1793],{"class":521},[50,2130,758],{"class":56},[50,2132,2133],{"class":63},"RESPONSE_MESSAGES",[50,2135,260],{"class":56},[50,2137,2138],{"class":63},"USER_CREATED",[50,2140,1252],{"class":56},[50,2142,2143],{"class":52,"line":989},[50,2144,834],{"class":56},[50,2146,2147],{"class":52,"line":995},[50,2148,1139],{"class":56},[10,2150,2151],{"id":2151},"テスト実行",[21,2153,2155],{"className":512,"code":2154,"language":514,"meta":30,"style":30},"npm run test:e2e\n",[28,2156,2157],{"__ignoreMap":30},[50,2158,2159,2161,2164],{"class":52,"line":53},[50,2160,522],{"class":521},[50,2162,2163],{"class":70}," run",[50,2165,2166],{"class":70}," test:e2e\n",[36,2168,2169],{"id":2169},"実行結果例",[21,2171,2174],{"className":2172,"code":2173,"language":26},[24],"PASS  src\u002Ftest\u002Fe2e\u002Fuser.e2e-spec.ts (33.623 s)\n  ユーザーAPI (E2E)\n    ユーザー一覧取得\n      ✓ 認証済みユーザーがユーザー一覧を取得できる (1748 ms)\n    ユーザー詳細取得\n      ✓ 認証済みユーザーがユーザー詳細を取得できる (1735 ms)\n    ユーザー作成\n      ✓ 認証済みユーザーがユーザーを作成できる (1493 ms)\n",[28,2175,2173],{"__ignoreMap":30},[10,2177,2179],{"id":2178},"cicd環境での実行","CI\u002FCD環境での実行",[14,2181,2182],{},[219,2183,2185],{"href":2184},"\u002Fblog\u002Fdocker-compose-github-actions-cicd","docker-compose + GitHub ActionsでCI\u002FCD環境を構築する方法はこちら",[10,2187,2188],{"id":2188},"まとめ",[14,2190,2191],{},"NestJSとJestを使ったE2Eテスト環境を構築することで、以下のメリットが得られます。",[188,2193,2194,2204,2213],{},[191,2195,2196,2199,2200,2203],{},[233,2197,2198],{},"統合テスト"," ",[28,2201,2202],{},"Test.createTestingModule()","で本番環境と同じDIコンテナを再現",[191,2205,2206,2199,2209,2212],{},[233,2207,2208],{},"独立性",[28,2210,2211],{},"beforeEach","でデータベースをリセットし、テスト間の依存を排除",[191,2214,2215,2218],{},[233,2216,2217],{},"実用性"," supertestでHTTPリクエストをプログラマティックにテスト",[14,2220,2221],{},"TypeORMのsynchronize機能を活用することで、テスト環境のセットアップも自動化できます。",[2223,2224,2225],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":30,"searchDepth":60,"depth":60,"links":2227},[2228,2229,2230,2233,2234,2235,2239,2244,2247,2248],{"id":12,"depth":60,"text":12},{"id":19,"depth":60,"text":19},{"id":33,"depth":60,"text":34,"children":2231},[2232],{"id":38,"depth":88,"text":38},{"id":228,"depth":60,"text":229},{"id":509,"depth":60,"text":509},{"id":542,"depth":60,"text":543,"children":2236},[2237,2238],{"id":549,"depth":88,"text":549},{"id":558,"depth":88,"text":558},{"id":655,"depth":60,"text":656,"children":2240},[2241,2242,2243],{"id":659,"depth":88,"text":659},{"id":1142,"depth":88,"text":1142},{"id":1713,"depth":88,"text":1713},{"id":2151,"depth":60,"text":2151,"children":2245},[2246],{"id":2169,"depth":88,"text":2169},{"id":2178,"depth":60,"text":2179},{"id":2188,"depth":60,"text":2188},"2021-11-28","NestJSとJestを使ったE2Eテストの実践的な導入方法を解説します。Test.createTestingModuleを使った統合テストの書き方から、TypeORMのsynchronize機能を活用したテスト環境構築まで詳しく紹介します。","md",{"tags":2253},[2254,2255,2256,2257,2258],"githubactions","jest","nestjs","cicd","typeorm","\u002Fblog\u002Fjest-nestjs-e2e-testing",{"title":5,"description":2250},"blog\u002Fjest-nestjs-e2e-testing","MWL6ASP_0aFswwfDyFfvMQF9peZ2fW8-edgICT5ri_w",1773664054277]