You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest测试时TypeORM同步未清空数据库,重复测试失败求助

Fixing Duplicate Data Errors in Jest Tests with TypeORM

Ah, I see the issue here! The synchronize: true option only handles schema synchronization when the connection is first established—it doesn't clear existing data between test runs. That's why your first test works (the table is empty initially), but the second one fails because the user from the first test is still lingering in the database.

Let's walk through a few reliable solutions to fix this:

Solution 1: Clear Data Before Each Test

You can explicitly clear all records from your entities before every test runs to ensure a fresh state each time.

Update your setup.js to add a beforeEach hook:

import { getConnection, getConnectionManager, getRepository } from "typeorm"
// Import all your entities here (adjust the path as needed)
import { User } from "../src/entities/User"

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()
})

// Clear data before each test starts
beforeEach(async () => {
  // Option A: Clear individual entities (simple for small apps)
  await getRepository(User).clear();
  // Repeat for other entities if you have them:
  // await getRepository(Post).clear();

  // Option B: Bulk truncate all tables (faster for larger apps)
  // const entities = getConnection().entityMetadatas;
  // await Promise.all(
  //   entities.map(entity => {
  //     return getConnection().query(`TRUNCATE TABLE "${entity.tableName}" CASCADE;`);
  //   })
  // );
})

afterAll(async () => {
  await getConnection().close()
})
  • clear(): Deletes all rows from the table (equivalent to DELETE FROM table). Safe for most cases, but doesn't reset auto-increment IDs.
  • TRUNCATE: Faster than DELETE, resets auto-increment IDs, and the CASCADE flag handles foreign key relationships (make sure this aligns with your schema rules).

A cleaner, more efficient approach is to wrap each test in a database transaction that gets rolled back after the test finishes. This way, no changes persist to the database at all.

Modify your setup.js like this:

import { getConnection, getConnectionManager } from "typeorm"

let queryRunner;

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()
})

beforeEach(async () => {
  queryRunner = getConnection().createQueryRunner();
  // Start a new transaction for the test
  await queryRunner.startTransaction();
})

afterEach(async () => {
  // Roll back all changes made during the test
  await queryRunner.rollbackTransaction();
  await queryRunner.release();
})

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

This method avoids manual table clearing entirely and guarantees a completely clean state for every test without messing with your schema or auto-increment values.

Why synchronize: true Didn't Work

Just to clarify: synchronize only updates the database schema (creating tables/columns) when the connection is first initialized. It never removes existing data—so once your first test inserts a user, that record stays until you explicitly delete it or roll back the transaction.

Pick the solution that fits your app size and workflow—transaction rollback is usually the most robust option for testing.

内容的提问来源于stack exchange,提问作者Jason Van Malder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:31:45