#javascript #node.js #asynchronous #async-await
#javascript #node.js #асинхронный #async-await
Вопрос:
У меня есть тест nodejs jest, и он завершается неудачей, потому что он не ждет Promise
.
it('returns an error if the ticket is already reserved', async () => {
const ticket = Ticket.build({
title: 'Concert',
price: 20
});
await ticket.save();
console.log('TICKET ID:', ticket.id);
const order = Order.build({
userId: 'asdasd',
status: OrderStatus.Created,
expiresAt: new Date(),
ticket
});
await order.save();
console.log('Order ID:', order.id);
await request(app)
.post('api/orders')
.set('Cookie', global.signin())
.send({
ticketId: ticket.id
})
.expect(400);
});
В контроллере я функционирую, как показано ниже.
import mongoose from 'mongoose';
import { Ticket } from '../models/ticket';
router.post('/api/orders',
...,
async (req: Request, res: Response) => {
const { ticketId } = req.body;
//Find the ticket the user is trying to order in the database
const ticket = await Ticket.findById(ticketId);
console.log('TICKET IN REQUEST: ', ticket);
if (!ticket) {
throw new NotFoundError();
}
....
res.status(201).send(order);
});
export { router as newOrderRouter };
Позвольте мне объяснить простым способом. В тесте я пытаюсь создать тикет в MongoDB и запрашиваю свой API, чтобы увидеть, создан тикет или нет.
Вы можете увидеть в console.log()
выводах ниже.
console.log
TICKET IN REQUEST: null
at src/routes/new.ts:27:17
console.log
TICKET ID: 5f6c3c7fd8bc648884890dc3
at src/routes/__tests__/new.test.ts:27:13
console.log
Order ID: 5f6c3c7fd8bc648884890dc4
at src/routes/__tests__/new.test.ts:38:13
Итак, как вы можете видеть, порядок журналов не является желаемым. API вызывается, не дожидаясь завершения других операций сохранения MongoDB. Операция сохранения Mongoose возвращает обещание. Поэтому он должен подождать. Но я не мог понять проблему. Есть идеи?
Ответ №1:
@ahmet, это потому, что вы сравниваете результаты до того, как обещание будет разрешено. вы должны использовать expect в promise.затем или сохраните результат ожидания в переменной, а затем сравните его (тестовый пример)
it('returns an error if the ticket is already reserved', async () => {
const ticket = Ticket.build({
title: 'Concert',
price: 20
});
await ticket.save();
console.log('TICKET ID:', ticket.id);
const order = Order.build({
userId: 'asdasd',
status: OrderStatus.Created,
expiresAt: new Date(),
ticket
});
await order.save();
console.log('Order ID:', order.id);
const result=await request(app)
.post('api/orders')
.set('Cookie', global.signin())
.send({
ticketId: ticket.id
});
result.expect(400);
//or this one
//request(app)
// .post('api/orders')
// .set('Cookie', global.signin())
// .send({
// ticketId: ticket.id
// }).then(result=>result.expect(400))
});
Комментарии:
1. Вы хорошо указали на проблему. Спасибо. Но result.expect не компилируется. Можете ли вы обновить свой ответ, просто удалив часть «result.» из «result.expect (400)» ожидание должно вызываться само по себе без запроса цепочки. Тогда я могу отметить как правильный ответ @Raghu Chahar
2. пожалуйста, игнорируйте синтаксическую ошибку, она должна быть похожа на expect (результат). toEqual(400). импортируйте expect из jest, если нет, проверьте синтаксис вашего инструмента тестирования.