How to unit test a transaction-wrapped function in Prisma?

Viewed 238

I'm very new to Prisma and NestJS. I have the following transaction-wrapped function that I want to unit test by mocking the internal function reserveSingleBook.

This is my code (it does a few actions in a for loop and I want all those actions to be successful before committing the transaction).

  async reserveBooks(reserveBooksDto: ReserveBoksDto): Promise<SuccessfulReservationResponse> {
    return await this.prisma.$transaction(async (prisma) => {

      const reservedBooksResponse = new SuccessfulReservationResponse();

      for (const reservation of reserveBooksDto.reservations){

        const bookBucket = await this.reserveSingleBook(
          prisma,
          reserveBooksDto.libraryId,
          reservation,
        );

        const successfulReservation = new SuccessfulReservation();
        successfulReservation.book_bucket_id = bookBucket.id;
        successfulReservation.units_reserved = reservation.units;

        reservedBookssResponse.successful_reservations.push(successfulReservation);    
      }

      return reservedBooksResponse
    })
  }

This is how I'm currently unit testing it:

    it('should throw an exception when at least a parent book does not exist', async () => {
  // Arrange
  const nonExistingParentBookId = 'non-existing-parentbook-id';
  const existingParentBookId = 'existing-parent-book-id'; 
  const mock = jest.spyOn(service, 'reserveSingleBook');
  mock
  .mockResolvedValueOnce(
    {
      parentBookId: existingParentBookId,
      reserved: 10,
      used: 0,
    } as BookBucket
  )
  .mockRejectedValueOnce(new NotFoundException())
  const reserveBooksDto = new ReserveBooksDto();
  reserveBooksDto.library_id= 'abcde';
  const firstReservation = new Reservation();
  firstReservation.book_id= nonExistingParentBookId;
  firstReservation.units = 10;
  const secondReservation = new Reservation();
  secondReservation.book_id= existingParentBookId;
  secondReservation.units = 10;
  reserveBooksDto.reservations = [firstReservation, secondReservation];

  // Act / Assert
  await expect(service.reserveBooks(
    reserveBooksDto
  )).rejects.toThrowError(NotFoundException);
  expect(mock).toBeCalledTimes(2);

  mock.mockRestore();
});

The unit test works PERFECTLY if I remove the transaction, since my second mock call returns the NotFoundException, which is then passed on to ReserveBooks.

However, when I have the transaction in place (don't want anything commited if anything fails), I get an 'undefined' resolved in my function call, instead of the exception thrown.

Does anybody know what I might be doing wrong?

Thanks in advance!!

0 Answers
Related