繁体   English   中英

在所有测试后 Jest/TypeORM 清除数据库

[英]Jest/TypeORM purge database after all tests

我想在所有笑话测试之后或之前删除我数据库中的所有条目。

这是我的 setup.js:

import { getConnection, getConnectionManager } from "typeorm"

beforeAll(async () => {
    const connectionManager = getConnectionManager()
    const connection = connectionManager.create({
        "type": "postgres",
        "host": "localhost",
        "port": 54320,
        "username": "test",
        "password": "test",
        "database": "test",
        "entities": ["../src/entities/*.ts"],
        "logging": false,
        "synchronize": true
    })
    await connection.connect()
})

afterAll(async () => {
    await getConnection().close()
})

我在 typeorm 文档中读到“同步”选项会用新的空表覆盖旧表,但它似乎不起作用。

这是我做的测试:

describe('POST /create', () => {
    it('Create a user', async () => {
        const user: IStringTMap<string> = {
            firstName: 'John',
            lastName: 'Doe',
            email: 'john.doe@test.com',
            password: 'test123!',
        }

        const res: Response = await request(app)
            .post('/create')
            .send(user)
            .expect(200)

        expect(res.type).toEqual('application/json')
        expect(res.body.email).toBe('john.doe@test.com')
        expect(res.body.password).toBe(undefined)
    })
})

第一个yarn test有效,但下一个无效(电子邮件已存在)

任何想法?

也许有点晚了,但也在寻找这个,这就是我想出的。

这只会删除实体内部的内容,而不是实体本身。

afterEach(async () => {

    // Fetch all the entities
    const entities = getConnection().entityMetadatas;

    for (const entity of entities) {
        const repository = getConnection().getRepository(entity.name); // Get repository
        await repository.clear(); // Clear each entity table's content
    }
});

编辑:如果您使用外键,请确保将{onDelete: "CASCADE"}属性添加到您的列中,以便正确删除所有记录。

更多信息可以在这里找到: https://github.com/typeorm/typeorm/issues/1460#issuecomment-366982161

您可以在您的 e2e 测试文件中使用单独的名称设置一个新数据库,并在导入 typeorm 模块时设置dropSchema: true选项。 您可以像在 AppModule 中一样导入 typeorm 模块

抱歉,我没有足够的声誉来回应 Michiel 的评论,但是,

如果您使用的是 postgreSQL 数据库并且您的表有外键约束,您的代码可能无法工作,因为根据postgreSQL 文档TRUNCATE 不会触发 ON DELETE 触发器

TRUNCATE TABLE 不会触发 ON DELETE 触发器。 相反,它会触发 BEFORE TRUNCATE 和 AFTER TRUNCATE 触发器。

因此,您可能必须使用EntityManager进行 SQL 查询,如下所示:

entityManager.query('TRUNCATE TABLE table_name CASCADE;')

希望你觉得这很有帮助。

您可能不必为此测试清除数据库。 您也可以使用类似faker的库并绕过 email 重复验证。 Faker 将在每次测试运行时产生一个唯一的用户。 将您的用户更改为:


import fake from 'faker';

const user: IStringTMap<string> = {
  firstName: faker.name.firstName(),
  lastName: faker.name.lastName(),
  email: faker.internet.email(),
  password: faker.internet.password()
}

这是使用 typeorm 完全清理数据库的一种快速有效的方法,它创建一个专用的 TestService,它在一个命令中截断所有实体:

 import { Inject, Injectable } from "@nestjs/common"; import { Connection } from "typeorm"; @Injectable() export class TestService { constructor(@Inject("Connection") public connection: Connection) {} public async cleanDatabase(): Promise<void> { try { const entities = this.connection.entityMetadatas; const tableNames = entities.reduce((prev, current, index) => { return index === entities.length - 1? prev + `"${current.tableName}"`: prev + `"${current.tableName}", `; }, ""); await this.connection.query(`TRUNCATE ${tableNames} CASCADE;`); console.log("[TEST DATABASE]: Clean"); } catch (error) { throw new Error(`ERROR: Cleaning test database: ${error}`); } } }

然后你可以在你的测试文件中调用这个 function :

 beforeEach(async () => { await testService.cleanDatabase(); });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM