Я хочу протестировать конечную точку POST своего экспресс-сервера с помощью супертеста. В почтальоне все работает нормально, но когда я пытаюсь передать параметры тела в тест, как видно из фрагментов кода ниже, оказывается, что параметры тела передаются неправильно. Я получаю тело запроса неопределенное.
import { Router } from 'express';
import { z } from 'zod';
import { Kysely } from 'kysely';
import * as sprints from './services';
import * as schema from './schema';
import { DB } from '../../database';
export function createSprintsRouter(db: Kysely<DB>) {
const router = Router();
router.post('/', async (req, res) => {
try {
const parsedInput = schema.parseNewSprintInput.parse(req.body);
const newSprint = await sprints.createSprint(db, parsedInput);
res.status(201).json(newSprint);
} catch (err) {
if (err instanceof z.ZodError) {
res.status(400).json({ err: err.errors });
} else {
res.status(500).json({ err: (err as Error).message });
}
}
});
return router;
}
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import supertest from 'supertest';
import express from 'express';
import { Kysely } from 'kysely';
import { createSprintsRouter } from '../controller';
import { getTestDbInstance } from '../../../database/db-test';
import type { DB } from '@/database/types';
describe('Sprints Controller', () => {
let testDb: Kysely<DB>;
let app: express.Application;
beforeAll(async () => {
testDb = getTestDbInstance();
const sprintsRouter = createSprintsRouter(testDb);
app = express().use('/sprints', sprintsRouter);
await testDb
.insertInto('sprints')
.values([
{ code: 'TST1', title: 'Test Sprint 1' },
{ code: 'TST2', title: 'Test Sprint 2' },
])
.execute();
});
afterAll(async () => {
await testDb.destroy();
});
describe("POST '/' endpoint", () => {
it('should create a new sprint', async () => {
const newSprint = { code: 'TST3', title: 'Test Sprint 3' };
const res = await supertest(app)
.post('/sprints')
.set('Content-Type', 'application/json')
.send(newSprint);
expect(res.status).toBe(201);
expect(res.body).toEqual(
expect.objectContaining({
code: 'TST3',
title: 'Test Sprint 3',
})
);
const allSprints = await supertest(app).get('/sprints');
expect(allSprints.body).toHaveLength(3);
});
});
});
Я искал решения этой проблемы, и в большинстве случаев вам приходилось использовать app.use(bodyParser.json()); перед маршрутами (которые я использую). Но проблема все еще сохраняется.
import express from 'express';
import './bot/discordBot';
import messages from './modules/messages/controller';
import messageTemplates from './modules/message-templates/controller';
import db from './database/index';
import { createSprintsRouter } from './modules/sprints/controller';
const app = express();
app.use(express.json());
const sprintsRouter = createSprintsRouter(db);
app.use('/messages', messages);
app.use('/templates', messageTemplates);
app.use('/sprints', sprintsRouter);
export default app;



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Полезная нагрузка должна быть в форме Content-Type, установленной кодом.
Он состоит из двух частей, о которых нужно заботиться.
Во-первых, в запросе должен быть указан тип контента, который в данном случае уже был выполнен.
Во-вторых, будет ли полезная нагрузка автоматически преобразована в строку с помощью супертеста перед ее публикацией. Кажется, он этого не делает. Это нужно сделать с помощью кода. В посте в цитате обсуждается то же самое. Наряду с установкой Content-Type он преобразует полезную нагрузку в строку, как показано ниже.
const payload = JSON.stringify(data);
Цитата:
Supertest+Jest не отправляет полезную нагрузку JSON
Проблема заключалась в том, что я не использовал экспресс express.json() в своем ТЕСТОВОМ файле Controller.spec.ts.
Я все еще учусь программировать, поэтому, возможно, я ошибаюсь с технической точки зрения, но, насколько я понимаю, промежуточное программное обеспечение express.json() помогает анализировать тело json, которое мы отправляем через запрос к конечной точке. Поскольку я не реализовал его в своем TEST-файле, мой req.body всегда был неопределенным (поскольку он не анализировался должным образом). Я реализовал это промежуточное ПО в своем основном файле app.ts, поэтому думал, что использую его везде, но, насколько я понимаю, мой тестовый файл использует отдельный экземпляр экспресса, поэтому его настройки отличаются от моего основного файла. Подводя итог, убедитесь, что вы используете промежуточное программное обеспечение express.json() в своей настройке :).
Ваше чтение должно быть правильным: когда express.json загружается в тест, он отправляет полезную нагрузку в виде строки. В противном случае он этого не делает. Кстати, удалось ли вам попробовать следующее решение, просто хотелось бы знать, работает оно или нет?
Привет, ни одно предложенное решение мне не помогло. Хотя express.json() все решил
Благодарим Вас за подтверждение. Также принял к сведению, что json() работает.
Привет. Удалось ли вам попробовать этот пост?