How to mock Prisma promises in unit tests?

Viewed 554

Let's say I have a transactional update of my database

...

const sendMoney = prisma.account.update({ where: { id: 1 }, data: { ... } })
const receiveMoney = prisma.account.update({ where: { id: 2 }, data: { ... } })

const [accountOfSender, accountOfReceiver] = await prisma.$transaction([
  sendMoney,
  receiveMoney
])

...

And I have a unit test which verifies this transaction

describe('The money transfer use case', () => {
  let mockedContext: MockContext
  let moneyTransferUseCase: MoneyTransferUseCase

  beforeEach(() => {
    mockedContext = createMockedContext()
    moneyTransferUseCase = new MoneyTransferUseCase(mockedContext.prisma)
  })

  it('should transfer money between two accounts', () => {
    ...

    const updatedAccount = { ... }

    mockedContext.prisma.account.update.mockReturnedValue(Promise.resolve(updatedAccount))
                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - throws an error

    ...
  })

Error message

TS2345: Argument of type 'Promise<Account>' is not assignable to parameter of type 'Prisma__AccountClinet<Account>'.
      Type 'Promise<Account>' is missing the following properties from type 'Prisma__AccountClient<Account>': _dmmf, _fetcher, _queryType, _rootField, and 11 more.

    63     mockedContext.prisma.account.update.mockReturnValue(Promise.resolve(updatedAccount))

the most important from this error message is this

Type 'Promise<Account>' is missing the following properties from type 'Prisma__AccountClient<Account>': _dmmf, _fetcher, _queryType, _rootField, and 11 more.

I can understand that Promise.resolve(updatedAccount) is not enough to mock the prisma promise. But how to mock it? Documentation says nothing about this. Any ideas?

Update

I thought about it for a bit and decided that I can mock prisma.$transaction([ ... ]) call itself

...

const expectedAccount1 = { ... }
const expectedAccount2 = { ... }

mockedContext.prisma.$transaction.mockResolvedValue([
  expectedAccount1,
  expectedAccount2
])

...

It exactly returns what I need but intermediate calls

...

const sendMoney = prisma.account.update({ where: { id: 1 }, data: { ... } }) // undefined
const receiveMoney = prisma.account.update({ where: { id: 2 }, data: { ... } }) // undefined

...

returns undefined during the test. I don't useе these results anywhere other than passing it to the prisma.$transaction function.

So it seems that test works as expected, but not sure if it is a good approach.

0 Answers
Related