nodejs async await не ожидает в тесте

#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, если нет, проверьте синтаксис вашего инструмента тестирования.