Тесты с app.request()
Тест — код, который сам отправляет запрос в приложение и проверяет ответ. В Hono для этого не нужен ни сервер, ни порт: метод app.request() передаёт запрос прямо в приложение и возвращает Response. Тесты запускает Vitest — популярная программа для тестов на TypeScript.
Приложение отдельно от сервера
Если тест импортирует src/index.ts, вместе с ним запустится сервер. Поэтому приложение выносят в отдельный файл. Создайте src/app.ts и перенесите туда всё, кроме serve():
// src/app.ts
import { Hono } from 'hono'
import posts from './routes/posts.js'
import auth from './routes/auth.js'
const app = new Hono()
app.route('/posts', posts)
app.route('/auth', auth)
export default appВ src/index.ts остаётся только запуск:
// src/index.ts
import { serve } from '@hono/node-server'
import app from './app.js'
serve({ fetch: app.fetch, port: Number(process.env.PORT ?? 3000) })Сервер работает как раньше, а src/app.ts можно импортировать в тестах.
Установка Vitest
npm install -D vitestСоздайте в корне проекта vitest.config.ts с переменными окружения для тестов:
// vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
env: {
DB_FILE: ':memory:',
JWT_SECRET: 'test-secret',
},
},
})Значение :memory: создаёт базу SQLite в памяти: она пустая при каждом запуске тестов и не трогает blog.db.
Первый тест
Создайте src/app.test.ts:
// src/app.test.ts
import { describe, expect, it } from 'vitest'
import app from './app.js'
describe('статьи', () => {
it('отдаёт список', async () => {
const res = await app.request('/posts')
expect(res.status).toBe(200)
expect(await res.json()).toEqual([])
})
it('возвращает 404 для несуществующей статьи', async () => {
const res = await app.request('/posts/999')
expect(res.status).toBe(404)
})
})Запустите тесты:
npx vitestВ терминале появятся два зелёных пункта и итог 2 passed. Vitest продолжит следить за файлами и перезапустит тесты при изменениях.
Запрос с телом и заголовками
Второй аргумент app.request() — те же настройки, что у fetch():
// src/app.test.ts
it('не создаёт статью без токена', async () => {
const res = await app.request('/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'Тест', body: 'Текст' }),
})
expect(res.status).toBe(401)
})Тест проверяет, что middleware requireAuth не пропускает запрос без токена.
Скрипт test
Добавьте в package.json строку "test": "vitest run" в раздел scripts. Команда npm test прогонит тесты один раз и завершится — так их запускают перед развёртыванием.
Частая ошибка
Тесты работают с той же базой blog.db, что и сервер разработки. Тест создаёт статьи, удаляет их, и через день проверка «список пуст» перестаёт проходить, а ваши данные портятся. Для тестов всегда задавайте отдельную базу, как :memory: в vitest.config.ts.