Jest测试时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 toDELETE FROM table). Safe for most cases, but doesn't reset auto-increment IDs.TRUNCATE: Faster thanDELETE, resets auto-increment IDs, and theCASCADEflag handles foreign key relationships (make sure this aligns with your schema rules).
Solution 2: Use Transactions for Tests (Recommended)
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

