如何在Jest中结合beforeEach与afterEach封装事务测试的重复逻辑?
Great question! You can absolutely cut out that repetitive transaction boilerplate by using Jest's beforeEach and afterEach hooks. This keeps your test logic focused and avoids duplicating the same wrapper code in every test case. Here's how to set it up:
Step 1: Declare a shared transaction variable
First, create a variable at the top of your test file to hold the active transaction instance across hooks and tests:
let trx;
Step 2: Initialize the transaction in beforeEach
Use beforeEach to start a transaction before every test, and store the transaction instance for later use:
beforeEach(async () => { // Start the transaction and capture the trx instance await app.transaction(async (transaction) => { trx = transaction; // Don't call rollback here—we'll handle cleanup in afterEach }); });
Step 3: Roll back the transaction in afterEach
Add an afterEach hook to automatically roll back the transaction after each test finishes, ensuring no test leaves behind dirty data that could affect subsequent tests:
afterEach(async () => { if (trx) { await trx.rollback(); trx = null; // Reset the variable to avoid cross-test contamination } });
Step 4: Write clean, focused test cases
Now your test logic can be written without the transaction wrapper—each test will run inside the transaction initialized in beforeEach:
test('successfully updates the record', async () => { // If your update function requires the trx instance to tie to the transaction, pass it here const a = await update(trx); expect(a).toBe(something); }); test('handles empty update request correctly', async () => { const result = await update(trx, {}); expect(result).toBe(null); });
Quick Note
If your database operations (like the update function) need explicit access to the transaction instance to run within the transaction scope, make sure to pass the stored trx variable to those functions. Most ORMs (like Knex or Sequelize) require this to link operations to the active transaction.
内容的提问来源于stack exchange,提问作者Jon Sud

