我是测试新手,想了解如何使用
mysql2
将 Kysely
数据库模拟为 vitest
的实例。我一直在关注 GitHub 提供的线程,但遇到了标题所示的错误:
数据库.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;
样品.规格.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);
来自 vi.mock 文档...
vi.mock 被提升(换句话说,移动)到文件顶部。这意味着无论您何时编写它(无论是在 beforeEach 内部还是测试内部),它实际上都会在此之前被调用。
这意味着真正运行的是这样的:
import { it, vi, expect } from "vitest";
// 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() }),
}),
};
});
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() }));
传递给
vi.mock
的块看不到DB
。您可以在导入时使用 vi.hoisted
。然后导入将与对 vi.mock
的调用一起提升。
import { it, vi, expect } from "vitest";
import db from "../database/database";
import { Kysely, MysqlDialect } from "kysely";
const { DB } = vi.hoisted(() => await import('../types/schema.types'));
请参阅使用 Vitest 模拟 Svelte Stores 的实用指南。
但是,提升使得代码非常难以理解,并且
vi.mock
充满了警告。考虑使用 vi.doMock
代替。请注意,您必须动态导入 ../database/database。