Недавно я экспериментировал с разработкой приложений с полным стеком, используя next.js и prisma. Кстати, взгляните на документацию prisma.

Интеграционное тестирование с Prisma

Один из способов имитации реальной среды — использовать Docker для инкапсуляции базы данных и некоторых тестовых данных. Это может быть развернуто и удалено с помощью тестов и, таким образом, работать как изолированная среда вдали от ваших производственных баз данных.

В этом руководстве предполагается, что на вашем компьютере установлены Docker и Docker Compose, а также настроен Jest в вашем проекте.

Я понимаю, о чем вы говорите, но… Вы так сильно хотите подготовиться к тестированию? Я хочу запускать тесты более легко и ловко.

И это важно, потому что документация не говорит нам, как легко очистить базу данных для каждого теста, что делает тесты независимыми и меняет их поведение в зависимости от порядка тестов.

Итак, давайте сделаем это.

На этот случай мы подготовили следующую схему.

datasource db {
  provider = "postgresql"
  url      = env("DB_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

npx prisma generate
Войти в полноэкранный режим

Выйти из полноэкранного режима

Во-первых, мы можем использовать Dotenv, чтобы указать URL-адрес базы данных для тестирования.

npm i -D dotenv
Войти в полноэкранный режим

Выйти из полноэкранного режима

# .env.test
DB_URL=postgresql://user:password@127.0.0.1:5432/example-test
Войти в полноэкранный режим

Выйти из полноэкранного режима

Далее мы определим процесс тестирования. Здесь воспользуемся функциями скрипта «pre» и «post».

{
  "scripts": {
    "pretest": "pg_ctl -D db/pgdata start && dotenv -e .env.test -- prisma migrate dev",
    "test": "dotenv -e .env.test -- mocha",
    "posttest": "pg_ctl -D db/pgdata stop"
  }
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Суть здесь в том, чтобы использовать API Dotenv для использования .env.test.

Последнее, что нам нужно сделать, это очистить базу данных, это первое, на что мы подали заявку. В случае мокко это делается с помощью beforeEach, afterEach.

import { PrismaClient } from '@prisma/client'

export class PrismaCleaner {
  constructor(prisma = new PrismaClient()) {
    this.prisma = prisma
    const propertyNames = Object.getOwnPropertyNames(prisma)
    this.modelNames = propertyNames.filter((name) => this.isModelName(name))
  }

  async clean() {
    console.log(`Database cleaning...`)
    return Promise.all(
      this.modelNames.map((modelName) => this.prisma[modelName].deleteMany())
    )
  }

  /**
   * @param {String} name
   * @returns {Boolean}
   */
  isModelName(name) {
    return !name.match(/^(_|\$)/)
  }
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

import * as assert from 'assert'
import { PrismaCleaner } from '../index.js'
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()
const cleaner = new PrismaCleaner()

describe('prisma-cleaner', () => {
  beforeEach(async () => {
    await cleaner.clean() # This
  })

  afterEach(async () => {
    await cleaner.clean() # This
  })

  describe('first creation', () => {
    it('creates a user', async () => {
      const user = await prisma.user.create({
        data: {
          name: 'John Lenon',
          email: 'john@example.com'
        }
      })
      assert.equal(user.name, 'John Lenon')
    })
  })

  describe('second creation', () => {
    it('creates a user', async () => {
      const user = await prisma.user.create({
        data: {
          name: 'John Wick',
          email: 'john@example.com'
        }
      })
      assert.equal(user.name, 'John Wick')
    })
  })
})
Войти в полноэкранный режим

Выйти из полноэкранного режима

Это все, что вам нужно сделать.

Кстати, я нашел несколько библиотек для этой очистки базы данных, но ни одна из них не работала идеально.

На этот раз я просто опубликую свою библиотеку.

Опыт разработки Prisma не так плох, как я думал, но я чувствую, что среда тестирования еще не готова, поэтому я хотел ее использовать!

Спасибо за чтение.