DT
Drizzle Teamfermentfan

Mocking Drizzle instance

Hey there, I am currently trying to find a good way to mock our drizzle instance for our unit test suite, but the nature of the usage of it makes it kinda hard. Is there somebody who is running a code base with a mocked drizzle?
fermentfan
fermentfan•289d ago
@bloberenober @Andrew Sherman Any idea? 😦
Andrii Sherman
Andrii Sherman•269d ago
Sorry for a late response, finally have free time to answer all questions in Discord https://discord.com/channels/1043890932593987624/1101108758127591435/1139240309939777719 I'll answer this question anyway We don't have mocks for drizzle. How do you want to use it? And why do you need to mock database for tests at all?
andrevandal
andrevandal•213d ago
hey @Andrew Sherman I have the same scenario here, I'm testing my repositories and I'm creating an unit test and I need to mock it hehe
bloberenober
bloberenober•212d ago
why not use something like sinon to stub/mock specific methods on the db? or if you are using vitest it has its own mocking API I think there's nothing specific to Drizzle that can't be mocked like anything else
andrevandal
andrevandal•212d ago
I've tried to mock using vitest but I'm facing some errors have you already use vitest to mock drizzle?
jakeleventhal
jakeleventhal•129d ago
// drizzle.mock.ts
import { DeepMockProxy, mockDeep, mockReset } from 'jest-mock-extended';

import { db } from '../src';

const drizzleMock: DeepMockProxy<typeof db> = mockDeep();

jest.mock('../src/index', () => ({
__esModule: true,
...jest.requireActual('../src/index'),
default: drizzleMock,
}));

beforeEach(() => {
mockReset(drizzleMock);
});

export default drizzleMock;
// drizzle.mock.ts
import { DeepMockProxy, mockDeep, mockReset } from 'jest-mock-extended';

import { db } from '../src';

const drizzleMock: DeepMockProxy<typeof db> = mockDeep();

jest.mock('../src/index', () => ({
__esModule: true,
...jest.requireActual('../src/index'),
default: drizzleMock,
}));

beforeEach(() => {
mockReset(drizzleMock);
});

export default drizzleMock;
Then add this to your jest config:
setupFilesAfterEnv: ['./path./to/drizzle.mock.ts']
setupFilesAfterEnv: ['./path./to/drizzle.mock.ts']
And here is a sample test
import drizzleMock from '../drizzle.mock';
import { NextApiRequest, NextApiResponse } from 'next';
import { createMocks } from 'node-mocks-http';

import someEndpoint from './get';

describe('/api/app-data/get', () => {
const data: AppData = { id: '123', maintenance: true };

it('should throws an error if no app data exists', async () => {
const { req, res } = createMocks({
method: 'GET'
});

await someEndpoint(req as unknown as NextApiRequest, res as unknown as NextApiResponse);

expect(drizzleMock.query.someTable.findFirst).toHaveBeenCalledTimes(1);
expect(res._getStatusCode()).toBe(500);
});

it('should return the app data when drizzle succeeds', async () => {
drizzleMock.query.someTable.findFirst.mockResolvedValueOnce(data);

const { req, res } = createMocks({
method: 'GET'
});
await someEndpoint(req as unknown as NextApiRequest, res as unknown as NextApiResponse);

expect(drizzleMock.query.someTable.findFirst).toHaveBeenCalledTimes(1);
expect(res._getStatusCode()).toBe(200);
expect(res._getData()).toStrictEqual(data);
});
});
import drizzleMock from '../drizzle.mock';
import { NextApiRequest, NextApiResponse } from 'next';
import { createMocks } from 'node-mocks-http';

import someEndpoint from './get';

describe('/api/app-data/get', () => {
const data: AppData = { id: '123', maintenance: true };

it('should throws an error if no app data exists', async () => {
const { req, res } = createMocks({
method: 'GET'
});

await someEndpoint(req as unknown as NextApiRequest, res as unknown as NextApiResponse);

expect(drizzleMock.query.someTable.findFirst).toHaveBeenCalledTimes(1);
expect(res._getStatusCode()).toBe(500);
});

it('should return the app data when drizzle succeeds', async () => {
drizzleMock.query.someTable.findFirst.mockResolvedValueOnce(data);

const { req, res } = createMocks({
method: 'GET'
});
await someEndpoint(req as unknown as NextApiRequest, res as unknown as NextApiResponse);

expect(drizzleMock.query.someTable.findFirst).toHaveBeenCalledTimes(1);
expect(res._getStatusCode()).toBe(200);
expect(res._getData()).toStrictEqual(data);
});
});
jakeleventhal
jakeleventhal•129d ago
youre welcome
No description
collinbxx
collinbxx•121d ago
@jakeleventhal How can I mock with select, insert and update?
jakeleventhal
jakeleventhal•121d ago
what i eneded up doing is basically using very few of those drizzle mock tests IMO, any test like that is kind of weak. its much better to either do an integration test or dont make those checks entirely
export default async () => {
const { container } = await SetupDatabase.start());

try {
// <TEST CODE>
} finally {
await container.stop();
}
};
export default async () => {
const { container } = await SetupDatabase.start());

try {
// <TEST CODE>
} finally {
await container.stop();
}
};
import { PostgreSqlContainer } from '@testcontainers/postgresql';
import { exec as execCb } from 'child_process';
import { ImportMock } from 'ts-mock-imports';
import { promisify } from 'util';

const exec = promisify(execCb);

export default class SetupDatabase {
private static startTestContainer = async (dbMount: string | undefined) => {
const container = await new PostgreSqlContainer('postgres:15.0')
.withUsername('postgres')
.withPassword('local')
.withDatabase('postgres')
.withBindMounts(
dbMount
? [
{
source: dbMount,
target: '/var/lib/postgresql/data'
}
]
: []
)
.start();

return container;
};

private static pushDatabaseSchema = async (url: string) => {
await exec(`npx drizzle-kit push:pg --config=../../../drizzle.config.ts`, {
env: {
...process.env,
DATABASE_URL: url,
}
});
};

static start = async (dbMount?: string) => {
// Start the container and get the database URL
const container = await this.startTestContainer(dbMount);
const url = container.getConnectionUri();

// Push the Prisma database schema
await this.pushDatabaseSchema(url);

ImportMock.mockOther(databasePackage, 'default', databasePackage.getDrizzleClient(url));

return { container};
};
}
import { PostgreSqlContainer } from '@testcontainers/postgresql';
import { exec as execCb } from 'child_process';
import { ImportMock } from 'ts-mock-imports';
import { promisify } from 'util';

const exec = promisify(execCb);

export default class SetupDatabase {
private static startTestContainer = async (dbMount: string | undefined) => {
const container = await new PostgreSqlContainer('postgres:15.0')
.withUsername('postgres')
.withPassword('local')
.withDatabase('postgres')
.withBindMounts(
dbMount
? [
{
source: dbMount,
target: '/var/lib/postgresql/data'
}
]
: []
)
.start();

return container;
};

private static pushDatabaseSchema = async (url: string) => {
await exec(`npx drizzle-kit push:pg --config=../../../drizzle.config.ts`, {
env: {
...process.env,
DATABASE_URL: url,
}
});
};

static start = async (dbMount?: string) => {
// Start the container and get the database URL
const container = await this.startTestContainer(dbMount);
const url = container.getConnectionUri();

// Push the Prisma database schema
await this.pushDatabaseSchema(url);

ImportMock.mockOther(databasePackage, 'default', databasePackage.getDrizzleClient(url));

return { container};
};
}
but if you really wanted to you can just extend the return types of each of those funcs
collinbxx
collinbxx•121d ago
I have a User creation function like this that uses the returning() function. I want to mock test it but don't know what to pass in below.
public async createUser(userData: CreateUserDto): Promise<User> {
if (isEmpty(userData)) throw new HttpException(400, "You're not userData");

const findUser: User = await DB.query.users.findFirst({
where: eq(users.email, userData.email),
});

if (findUser)
throw new HttpException(
409,
`You're email ${userData.email} already exists`,
);

const hashedPassword = await hash(userData.password, 10);
const createdUser: User = (
await DB.insert(users)
.values({
...userData,
password: hashedPassword,
})
.returning()
)[0];

return createdUser;
}
public async createUser(userData: CreateUserDto): Promise<User> {
if (isEmpty(userData)) throw new HttpException(400, "You're not userData");

const findUser: User = await DB.query.users.findFirst({
where: eq(users.email, userData.email),
});

if (findUser)
throw new HttpException(
409,
`You're email ${userData.email} already exists`,
);

const hashedPassword = await hash(userData.password, 10);
const createdUser: User = (
await DB.insert(users)
.values({
...userData,
password: hashedPassword,
})
.returning()
)[0];

return createdUser;
}
describe('[POST] /users', () => {
it('response Create user', async () => {
const userData: CreateUserDto = {
email: 'test@email.com',
password: 'q1w2e3r4!',
};

const usersRoute = new UserRoute();

drizzleMock.query.users.findFirst.mockResolvedValueOnce(null);
drizzleMock.insert.mockReturnValueOnce(???);

const app = new App([usersRoute]);
return request(app.getServer())
.post(`${usersRoute.path}`)
.set('Authorization', `Bearer ${tokenData.token}`)
.send(userData)
.expect(201);
});
});
describe('[POST] /users', () => {
it('response Create user', async () => {
const userData: CreateUserDto = {
email: 'test@email.com',
password: 'q1w2e3r4!',
};

const usersRoute = new UserRoute();

drizzleMock.query.users.findFirst.mockResolvedValueOnce(null);
drizzleMock.insert.mockReturnValueOnce(???);

const app = new App([usersRoute]);
return request(app.getServer())
.post(`${usersRoute.path}`)
.set('Authorization', `Bearer ${tokenData.token}`)
.send(userData)
.expect(201);
});
});
KHRM
KHRM•28d ago
did you ever figure this out? it gives me issues when im not using the query method
No description
Want results from more Discord servers?
Add your server
More Posts
How to run a Cleanup ScriptI saw someone provide a nice script to empty the database, here's a version of it: ```typescript aAdd conditions on relationshipsIs it possible to add conditions when declaring relationships? In my example, I have books that havhow is remove nested relation name "collection". Used many-to-many relationship.request: await db.query.products.findMany({ with: { collections: { I tried date format in the where clause it showing me an error.this is the query im converting SELECT *, (SELECT COUNT(*) from `daily_check` WHERE (`daily_checks`groupby multiple thingsthe SQL query I want to convert ends with: ```GROUP BY u.user_id, e.ExerciseID;``` I see no whUnwrap the return type of a Subquery, native jsonAgg support or RQ Join Names?Hi There, I am currently investigating Drizzle ORM and seeing if I can bend it to do everything I Unform methods for result accessIs there a set of uniform methods for accessing the results of a query? Could be good to have somethCannot query DB table get `COALESCE types smallint and text cannot be matched`When i run the following query ```javascript let tc = await db.query.ATable.findFirst({ where: Cannot Access Primary Key on TableHello, I am trying to access the primary key named `id` on the following table: ```ts export const Typescript build fails, pointing to internal types.My typescript build fails with 4 errors, all of them pointing to internal type declarations. Is theronConflictDoNothing does not exist on planetscale clienti am getting an "Property onConflictDoNothing does not exist on type" on the following script.... `Are relational queries supported on mysql?I'm new to this ORM and I'm having trouble getting relational queries to work. Normal db.select()Is there a way to write a query that orders and filters based on an array of possible options?I'm trying to do some server-side filtering and sorting for a table, and I ended up writing this forcannot set alias for composite primary key, getting (errno 1059) (sqlstate 42000) errorsMy table has the following schema -> ```ts export const emergencyContactPhoneNumber = mysqlTable( Help with query writingHi, I'm hoping someone will help me with this query. I have the following query in one of my serviceMySql NOW() in DrizzleHi! I might be struggling because this is hard to search for, but I'm wondering if it's possible to Postgres: install plugin during migrationSo, I'm using Drizzle with Postgres and am using uuid for the id fields. For that, i need to run theIntrospect failing no pg_hba.conf entry for hostI'm trying to introspect an existing postgres db. It's hosted on heroku and I'm facing `no pg_hba.coIs there a way I can use relational types?I'm currently trying to make a helper function that essentially wraps a database call, but I can't sDifference in using unique() on the column definition vs the index?What is the different between using something like `name: varchar('name', { length: 256 }).unique(