mmag

ハマったことメモなど

おとなしくテスト回す前にDBリセットしたほうがいい

SvelteKitとDrizzle使って https://movieoftheyear.cc をつくったんだけど、テスト回すたびにDBにレコードが残るのが我慢ならず、ちょっとググってこんなのを書いて

import { test } from 'vitest';
import { db } from '$lib/server/db';
import type { Database } from '$lib/server/db';
import { TransactionRollbackError } from 'drizzle-orm';

export const testWithTransaction = test.extend<{ tx: Database }>({
  tx: async ({}, use) => {
    try {
      await db.transaction(async (tx) => {
        await use(tx);
        tx.rollback();
      });
    } catch (e) {
      if (e instanceof TransactionRollbackError) {
        // rolled back
      } else {
        throw e;
      }
    }
  },
});

こう使っていたんだけど

import { describe, expect } from 'vitest';
import { testWithTransaction } from '$lib/server/test';
import { registerUser, findUserBySlug } from '$lib/server/account';

describe('registerUser', () => {
  testWithTransaction('inserts user and session records', async ({ tx }) => {
    const { token, session } = await registerUser(tx);

    expect(token).toMatch(/^[a-z0-9]{30,}$/);
    expect(session).toMatchObject({
      userId: expect.any(String),
      expiresAt: expect.any(Date),
    });
  });
});

これだとbeforeEach使えないしテスト対象の引数に渡せるようにしておかないといけなかったり、微妙なのでやめたほうがよさそう。