NestJS + TypeORM + PostgreSQLにおけるTypeORMの設定のentitiesの設定について、サーバーを起動する場合と、npm run testでテストする場合とで、設定をかえないといけないです。
※ぐぐると、entitiesの設定についてはまっている方が多いけど、いまいちしゃきっとした回答が見つかりませんでした。自分もいろいろ試行錯誤した結果、下に書いた内容に行き着いたのですが、どうしてそうなるのかをちゃんと説明できない(調べられない)です。分かる方にご教示頂きたいです…
[困ったこと]
NestJS + TypeORM + PostgreSQLの構成でサーバーは問題なく起動し、リクエストに対してレスポンスを返すのですが、npm run test(Jestによるテスト)をすると以下のエラーが発生しテストが失敗する。
[TypeORMの設定]
app.module.tsで
ormconfig.jsonの内容は以下のとおり。
[解決方法]
npm run test(Jestによるテスト)の場合は、entitiesを以下のように設定する。
getEntites()の内容は以下のとおり。
[考えたこと]
[試験環境]
https://github.com/hiroin/typeorm-setting-entities
※ぐぐると、entitiesの設定についてはまっている方が多いけど、いまいちしゃきっとした回答が見つかりませんでした。自分もいろいろ試行錯誤した結果、下に書いた内容に行き着いたのですが、どうしてそうなるのかをちゃんと説明できない(調べられない)です。分かる方にご教示頂きたいです…
[困ったこと]
NestJS + TypeORM + PostgreSQLの構成でサーバーは問題なく起動し、リクエストに対してレスポンスを返すのですが、npm run test(Jestによるテスト)をすると以下のエラーが発生しテストが失敗する。
RepositoryNotFoundError: No repository for "Users" was found. Looks like this entity is not registered in current "default" connection?
[TypeORMの設定]
app.module.tsで
@Module({ imports: [ TypeOrmModule.forRoot(), TypeOrmModule.forFeature([Users]), ],とし、ルートディレクトリにormconfig.jsonを配置した。
ormconfig.jsonの内容は以下のとおり。
{ "name": "default", "type": "postgres", "host": "localhost", "port": 5432, "username": "postgres", "password": "postgres", "database": "pong", "entities": ["dist/entities/**/*.entity.js"], "migrations": ["dist/migrations/**/*.js"], "logging": false, "synchronize": false }
[解決方法]
npm run test(Jestによるテスト)の場合は、entitiesを以下のように設定する。
["./src/entities/**/*.entity.ts"]具体的には、spec.tsファイルを以下のように書いた。
describe("AppController", () => { let appController: AppController; let app: TestingModule; beforeAll(async () => { app = await Test.createTestingModule({ imports: [ TypeOrmModule.forRoot(), TypeOrmModule.forRootAsync({ useFactory: async () => Object.assign(await getConnectionOptions(), { entities: getEntites(), }), }), TypeOrmModule.forFeature([Users]), ], (中略) }).compile(); appController = app.get(AppController); }); afterAll(() => app.close());
getEntites()の内容は以下のとおり。
export function getEntites() { return ["./src/entities/**/*.entity.ts"]; }
[考えたこと]
"entities": ["dist/entities/**/*.entity.js"],と設定して、Jestでテストをしようとすると
RepositoryNotFoundError: No repository for "Users" was found. Looks like this entity is not registered in current "default" connection?となる。
"entities": ["./src/entities/**/*.entity.ts"],と設定して、npm run start:devすると
[Nest] 17012 - 2021/12/08 16:53:42 ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)... D:\42\ft_transcendence\github\pong\server\src\entities\accomplishes.entity.ts:1 import { ^^^^^^ SyntaxError: Cannot use import statement outside a moduleとなる。 以上から、NestJSはコンパイルされたJavaScriptで動作するので、TypeORMに読み込ませるEntityの情報はJavaScript(.js)でなければならない(importがSyntaxErrorになる)のに対して、Jestでテストをする場合、テストファイルはTypeScriptで書かれているものをJestがトランスコンパイルして生成されたJavascriptで動作するので、TypeORMに読み込ませるEntityの情報は(おそらく依存関係の解決のために)TypeScript(.ts)でなければならない(dist/entities/*/.entity.jsを読み込んでくれない?)のだと思います、たぶん… ちゃんとした理由をご存知でしたらご教示頂きたいです。
[試験環境]
https://github.com/hiroin/typeorm-setting-entities