Trouble running JEST testing in Hono for Cloudfare Workers

So, I have an API setup in Hono with cloudfare workers and I setup the JEST tests but they don't seem to inject the D1 DB into the context environment so I can use it to init the DB and perform the associated request actions. I am trying to just do this locally. What am I doing wrong? I'm kinda new so any help would be much appreciated. The test just sends requests to the server, do I have to manually add the DB to the context so Drizzle ORM can be initialized or something else. Sorry, if I'm not using the right words to describe it
7 Replies
rphlmr ⚡
rphlmr ⚡12mo ago
It'll not easy to help you since testing is a vast subject. Do you want to achieve unit testing, calling your real code?
rphlmr ⚡
rphlmr ⚡12mo ago
Hono has just released a test helper https://hono.dev/helpers/testing
Testing Helper - Hono
Ultrafast web framework for Cloudflare Workers, Fastly Compute@Edge, Deno, Bun, Vercel, Lagon, Node.js, and others. Fast, but not only fast.
rphlmr ⚡
rphlmr ⚡12mo ago
I am a hono user (with node) but I haven't done any testing yet 😅
walkersyed581
walkersyed58112mo ago
Thanks. I'll try this, hopefully will work
Domski
Domski2mo ago
@walkersyed581 Hey sorry for waking this thread but I am struggling to get hono+cf workers set up with drizzle+d1, do you have a repo you can share? I think the db object needs to be set to the hono context during a middleware initialization but drizzle is using .env in its drizzle.config.ts so I'm not sure how to combine the two things.
export const dbMiddleware = createMiddleware<Environment>(async (c, next) => {
console.log('Creating database middleware...')
const client = createClient({
url: c.env.TURSO_CONNECTION_URL!,
authToken: c.env.TURSO_AUTH_TOKEN!
})

const db = drizzle(client)
c.set('db', db)
await next()
})

// --

export default defineConfig({
schema: './src/db/schema/*schema.ts',
out: './drizzle',
dialect: 'sqlite',
driver: 'turso',
dbCredentials: {
url: '??',
authToken: '??'
}
}) satisfies Config
export const dbMiddleware = createMiddleware<Environment>(async (c, next) => {
console.log('Creating database middleware...')
const client = createClient({
url: c.env.TURSO_CONNECTION_URL!,
authToken: c.env.TURSO_AUTH_TOKEN!
})

const db = drizzle(client)
c.set('db', db)
await next()
})

// --

export default defineConfig({
schema: './src/db/schema/*schema.ts',
out: './drizzle',
dialect: 'sqlite',
driver: 'turso',
dbCredentials: {
url: '??',
authToken: '??'
}
}) satisfies Config
certified dirtiboi
This is how I have it set up - I pass the cloudflare account and D1 credentials in the dbCredentials node.
// If we are in production, we use the Cloudflare production database else we use the local database
export default defineConfig({
dialect: 'sqlite',
schema: './src/services/db/schema/*',
out: './migrations',
...(process.env.NODE_ENV === 'production'
? {
driver: 'd1-http',
dbCredentials: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
databaseId: process.env.CLOUDFLARE_D1_ID,
token: process.env.CLOUDFLARE_D1_TOKEN,
ssl: false
}
}
: {
dbCredentials: {
url: getLocalD1DB()
}
})
});
// If we are in production, we use the Cloudflare production database else we use the local database
export default defineConfig({
dialect: 'sqlite',
schema: './src/services/db/schema/*',
out: './migrations',
...(process.env.NODE_ENV === 'production'
? {
driver: 'd1-http',
dbCredentials: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
databaseId: process.env.CLOUDFLARE_D1_ID,
token: process.env.CLOUDFLARE_D1_TOKEN,
ssl: false
}
}
: {
dbCredentials: {
url: getLocalD1DB()
}
})
});
I then use a middleware like yours (but mine is its own file) to initialize the DB on the first hono request and reuse that connection on subsequent requests (as needed):
import { drizzle, DrizzleD1Database } from 'drizzle-orm/d1';

const schema = { schemas }; // change this to your schema/s

let db: DrizzleD1Database<typeof schema> | null = null;

export function getDbConnection(env: D1Database): DrizzleD1Database<typeof schema> {
if (!env) {
throw new Error("Environment variable for database is not defined");
}

if (!db) {
db = drizzle(env, { schema });
}

return db;
}
import { drizzle, DrizzleD1Database } from 'drizzle-orm/d1';

const schema = { schemas }; // change this to your schema/s

let db: DrizzleD1Database<typeof schema> | null = null;

export function getDbConnection(env: D1Database): DrizzleD1Database<typeof schema> {
if (!env) {
throw new Error("Environment variable for database is not defined");
}

if (!db) {
db = drizzle(env, { schema });
}

return db;
}
You might need to mess with the client settings since you seem to be using Turso. Also, I'm using wrangler which auto-generated an env.d.ts file that contains my Cloudflare env types that are needed to make a db connection.
Domski
Domski2mo ago
I'll give that a go, thanks for the help!
Want results from more Discord servers?
Add your server