Testing: how can i use transaction in my test and controller

when i run the test i got this error

my test

'use strict'

const { test, trait } = use('Test/Suite')('User')

const Factory = use('Factory')

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const User = use('App/Models/User')

trait('Test/ApiClient')
trait('DatabaseTransactions')
trait('Auth/Client')

test('it should be able to create new user', async ({ assert, client }) => {
  const user = await createUserForLogin()

  const { name, email } = await Factory.model('App/Models/User').make({
    password: '123456'
  })

  const response = await client
    .post('/users')
    .header('accept', 'application/json')
    .send({
      name,
      email,
      password: '123456',
      password_confirmation: '123456'
    })
    .loginVia(user, 'jwt')
    .end()

  response.assertStatus(201)
  assert.deepEqual(
    { name, email },
    {
      name: response.body.name,
      email: response.body.email
    }
  )
  assert.isAbove(response.body.id, 1, 'the id is above than 1')
})

my controller

async store({ request, response, auth }) {
    const data = request.only(['email', 'name', 'password'])

    const count = await Database.from('users').count('* as total')

    if (count[0].total < 3) {
      const trx = await Database.beginTransaction()

      const user = await User.create(data, trx)

      await UserActivity.create(
        {
          user_id: auth.user.id,
          description: `created a user ${user.name}`
        },
        trx
      )

      await trx.commit()

      return response.status(201).json(user)
    } else {
      return response.status(400).json({
        error: {
          message: 'only 3 users'
        }
      })
    }
  }

when i remove the trait(‘DatabaseTransactions’) work. but I run out of transactions with each test

and i use sqlite3 for test database

2 Likes

I have the same problem…
When I try to make a request by insomnia, the whole function works correctly. However, when I’m doing functional tests, everything fails.

Haven’t tried DatabaseTransactions with SQLite, but there’s one problem (not sure if it solves your issue tho)
If code reaches to catch block transaction is left uncommited and not rolled back. Transaction is left open forever