使用 Supertest 测试 Express 应用程序时,TypeORM 无法找到连接

TypeORM fails to find a connection when testing an Express app with Supertest

我正在构建一个 TypeScript 节点。js/Express 应用程序并开始使用 Jest 和 Supertest 实施一些集成测试,但即使在成功设置 TypeORM 连接后,我的测试也会失败,提示未找到连接。

这是我目前在我的测试文件中的内容:

let conn: Connection;

describe('tests admin routes', () => {
  beforeAll(async () => {
    conn = await createConnection();
    registerDeps(); // registers dependencies on my tsyringe container
  });

  afterAll(async () => {
    await conn.close();
  });

  it('should be able to authenticate admins', async () => {
    const { status } = await supertest(app) // app is an `Express` "instance"
      .post('/admins/auth')
      .send({
        email: 'myemail@company.com',
        password: 'mypassword',
      });

    console.log(status);
  });
});

如果我在我的终端上 运行 jest,我会得到以下信息:

FAIL  src/modules/admin/web/controllers/__tests__/AdminsController.spec.ts
  ● Test suite failed to run

    ConnectionNotFoundError: Connection "default" was not found.

      at new ConnectionNotFoundError (src/error/ConnectionNotFoundError.ts:8:9)
      at ConnectionManager.Object.<anonymous>.ConnectionManager.get (src/connection/ConnectionManager.ts:40:19)
      at Object.getRepository (src/index.ts:284:35)
      at new VideosRepositoryTORM (src/modules/course/infrastructure/lib/typeorm/repositories/VideosRepositoryTORM.ts:11:26)
      at Object.<anonymous> (src/modules/course/web/controller/CoursesController.ts:12:26)
      at Object.<anonymous> (src/modules/course/web/routers/courses.router.ts:5:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.89 s
Ran all test suites.

我有点困惑,因为 none 我的控制器调用的服务使用 VideosRepositoryTORM,如果我使用 conn 来解析存储库,则执行 conn.getRepository(Admin) 例如(Admin 是一个 TypeORM 实体),然后调用任何 Repository 方法,如 findquery 它实际上 returns 数据存储在数据库中,这让我相信我的连接确实已经建立并且正在工作。

此外,当 运行 和 node 时,我的应用程序工作正常,它只是在测试中输出此连接错误。值得一提的是,我正在使用 tsyringe 将存储库实现注入到我的服务中,但我认为这不会导致问题。有人知道这里会发生什么吗?

这里发生的事情是我的 'ormconfig.js' 文件上有两个连接:

module.exports = [
  {
    name: 'default',
    type: 'postgres',
    // ...
  },
  {
    name: 'test',
    type: 'postgres',
    // ...
  },
];

而且,如果没有另外说明,typeorm 总是会尝试使用 'default' 连接进行操作。例如,使用 getRepository(Teacher) 加载实体存储库等同于 getRepository(Teacher, 'default')。所以 typeorm 实际上是在创建连接,但是当我 运行 我的集成测试时它试图使用 'default' 而不是 'test'

当您使用多个连接时,您可以采取一些措施来解决此问题:

  1. 硬编码您每次要使用的连接(在大多数情况下效果不佳);

  2. 设置环境变量并将它们用于select你想要的连接(这是最灵活的选项);

  3. 加载所需的连接配置并将其“重命名”为 'default',或创建连接时您可能使用的任何其他名称。

在我的例子中,我选择了第三个选项,所以我在测试中加入了以下内容:

beforeAll(async () => {
    const connOpts = await getConnectionOptions('test');
    conn = await createConnection({ ...connOpts, name: 'default' });
    // ...
});

如果您要使用两个以上的连接,第二个选项可能会更好,但第三个也可以。完全由您决定。