I'm new to testing and would like to learn how to mock the mysql2
database as an instance of Kysely
with vitest
. I've been following a thread provided from GitHub, but I encountered the error as the title it says:
database.ts
import * as dotenv from "dotenv";
import { type DB } from "../types/schema.types";
import { createPool, } from "mysql2";
import { Kysely, MysqlDialect } from "kysely";
dotenv.config();
export const dialect = new MysqlDialect({
pool: createPool({
database: `${process.env.DATABASE}`,
host: `${process.env.DATABASE_HOST}`,
port: process.env.DATABASE_PORT as unknown as number,
user: `${process.env.USER}`,
password: process.env.PASSWORD,
waitForConnections: true,
multipleStatements: true,
charset: "utf8mb4",
connectionLimit: `${process.env.DATABASE_CONNECTION_LIMIT}` as unknown as number,
queueLimit: 0,
}),
})
const db = new Kysely<DB>({ dialect });
export default db;
sample.spec.ts
import { it, vi, expect } from "vitest";
import db from "../database/database";
import { DB } from "../types/schema.types";
import { Kysely, MysqlDialect } from "kysely";
// Test case
it("Get user count", async () => {
const mocks = vi.hoisted(() => ({ query: vi.fn() }));
// Mocking database module
vi.mock("../database/database", async (importOriginal) => {
const actualModule = await importOriginal<typeof import("../database/database")>();
return {
...actualModule,
__esModule: true,
ownerDb: new Kysely<DB>({
dialect: new MysqlDialect({ pool: vi.fn() }),
}),
};
});
mocks.query.mockResolvedValue({ rows: [{ count: 1 }] });
const query = db
.selectFrom("users")
.select((eb) => eb.fn.count<number>("users.user_id").as("count"));
const { count } = await db
.selectNoFrom((eb) => eb.fn.coalesce(query, eb.lit(0)).as("count"))
.executeTakeFirstOrThrow();
expect(count).toBe(1);
From the vi.mock documentation...
That means what's really run is this:
The block passed to
vi.mock
cannot seeDB
. You can usevi.hoisted
on the import. Then the import will be hoisted along with the call tovi.mock
.See A Practical Guide to Mocking Svelte Stores with Vitest.
However, hoisting makes the code very difficult to understand and
vi.mock
is loaded with caveats. Consider usingvi.doMock
instead. Note that you will have to dynamically import ../database/database.