Skip to content

test(cloudflare): Add test for hono cloudflare #16360

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "cloudflare-hono",
"scripts": {
"dev": "wrangler dev",
"build": "wrangler deploy --dry-run --var E2E_TEST_DSN=$E2E_TEST_DSN",
"test": "vitest",
"typecheck": "tsc --noEmit",
"cf-typegen": "wrangler types --env-interface CloudflareBindings",
"test:build": "pnpm install && pnpm build",
"//": "Just checking if it builds correctly and types don't break",
"test:assert": "pnpm typecheck"
},
"dependencies": {
"@sentry/cloudflare": "latest || *",
"hono": "4.7.10"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "^0.8.31",
"@cloudflare/workers-types": "^4.20250521.0",
"vitest": "3.1.0",
"wrangler": "^4.16.0"
},
"volta": {
"extends": "../../package.json"
},
"sentryTest": {
"optional": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Generated by Wrangler on Mon Jul 29 2024 21:44:31 GMT-0400 (Eastern Daylight Time)
// by running `wrangler types`

interface Env {
E2E_TEST_DSN: '';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Hono } from 'hono';
import * as Sentry from '@sentry/cloudflare';

const app = new Hono();

app.get('/', ctx => {
return ctx.json({ message: 'Welcome to Hono API' });
});

app.get('/hello/:name', ctx => {
const name = ctx.req.param('name');
return ctx.json({ message: `Hello, ${name}!` });
});

app.get('/error', () => {
throw new Error('This is a test error');
});

app.onError((err, ctx) => {
console.error(`Error occured: ${err.message}`);
return ctx.json({ error: err.message }, 500);
});

app.notFound(ctx => {
return ctx.json({ message: 'Not Found' }, 404);
});

export default Sentry.withSentry(
(env: Env) => ({
dsn: env?.E2E_TEST_DSN,
tracesSampleRate: 1.0,
}),
app,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module 'cloudflare:test' {
// ProvidedEnv controls the type of `import("cloudflare:test").env`
interface ProvidedEnv extends Env {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { describe, expect, it } from 'vitest';
import app from '../src/index';
import { SELF, createExecutionContext, env, waitOnExecutionContext } from 'cloudflare:test';

describe('Hono app on Cloudflare Workers', () => {
describe('Unit Tests', () => {
it('should return welcome message', async () => {
const res = await app.request('/', {}, env);
expect(res.status).toBe(200);
const data = await res.json();
expect(data).toEqual({ message: 'Welcome to Hono API' });
});

it('should greet a user with their name', async () => {
const res = await app.request('/hello/tester', {}, env);
expect(res.status).toBe(200);
const data = await res.json();
expect(data).toEqual({ message: 'Hello, tester!' });
});

it('should handle errors with custom error handler', async () => {
const res = await app.request('/error', {}, env);
expect(res.status).toBe(500);
const data = await res.json();
expect(data).toHaveProperty('error', 'This is a test error');
});

it('should handle 404 with custom not found handler', async () => {
const res = await app.request('/non-existent-route', {}, env);
expect(res.status).toBe(404);
const data = await res.json();
expect(data).toEqual({ message: 'Not Found' });
});
});

// Integration test style with worker.fetch
describe('Integration Tests', () => {
it('should fetch the root endpoint', async () => {
// Create request and context
const request = new Request('http://localhost/');
const ctx = createExecutionContext();

const response = await app.fetch(request, env, ctx);

await waitOnExecutionContext(ctx);

expect(response.status).toBe(200);
const data = await response.json();
expect(data).toEqual({ message: 'Welcome to Hono API' });
});

it('should handle a parameter route', async () => {
// Create request and context
const request = new Request('http://localhost/hello/cloudflare');
const ctx = createExecutionContext();

const response = await app.fetch(request, env, ctx);

await waitOnExecutionContext(ctx);

expect(response.status).toBe(200);
const data = await response.json();
expect(data).toEqual({ message: 'Hello, cloudflare!' });
});

it('should handle errors gracefully', async () => {
const response = await SELF.fetch('http://localhost/error');

expect(response.status).toBe(500);
const data = await response.json();
expect(data).toHaveProperty('error', 'This is a test error');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["@cloudflare/workers-types/experimental", "@cloudflare/vitest-pool-workers"]
},
"include": ["./**/*.ts", "../src/env.d.ts"],
"exclude": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
"lib": [
"ESNext"
],
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx"
},
"include": ["src/**/*"],
"exclude": ["test", "node_modules"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineWorkersProject } from '@cloudflare/vitest-pool-workers/config'

export default defineWorkersProject(() => {
return {
test: {
globals: true,
poolOptions: {
workers: { wrangler: { configPath: './wrangler.toml' } },
},
},
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name = "cloudflare-hono"
main = "src/index.ts"
compatibility_date = "2023-10-30"
compatibility_flags = ["nodejs_compat"]

# [vars]
# E2E_TEST_DSN = ""
Loading