- Published on
Fitnotes (4. díl) - Implementace CRUD testů pro Prisma model
Implementace CRUD testů pro model Workout
V tomto dílu navážu na předchozí článek, ve kterém jsem si vydefinoval testovací scénáře pro Prisma model Workout. V tomto článku ukážu implementaci CRUD testů pomocí frameworku Jest.
1. Vytvoření validního záznamu
Nejprve vytvořím test, který ověří, že dokážeme vložit platný záznam do databáze.
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const today = new Date(Date.now())
const workoutDay = new Date('2024-10-11')
describe('Workout model', () => {
it('should create a valid workout record', async () => {
const workout = await prisma.workout.create({
data: {
date: workoutDay,
exercise: 'Bench Press',
category: 'Chest',
weight: 100,
weightUnit: 'kgs',
reps: 10,
},
})
console.log(workout)
expect(Object.keys(workout).length).toBe(11)
expect(workout).toHaveProperty('id')
expect(workout.date).toEqual(workoutDay)
expect(workout.exercise).toBe('Bench Press')
expect(workout.category).toBe('Chest')
expect(workout.weight).toBe(100)
expect(workout.weightUnit).toBe('kgs')
expect(workout.reps).toBe(10)
expect(workout.distance).toBeNull()
expect(workout.distanceUnit).toBeNull()
expect(workout.time).toBeNull()
expect(workout.createdAt.getTime()).toBeGreaterThan(today.getTime())
expect(workout.createdAt.getTime()).toBeLessThan(today.getTime() + 10 * 1000)
})
})
Co obsahuje konstanta workout?
workout obsahuje objekt, který Prisma vrátí po úspěšném vložení záznamu do databáze. Funkce prisma.workout.create(...) odešle SQL dotaz do PostgreSQL databáze, vloží data do tabulky Workout a vrátí javascriptový objekt, jehož property pak v testu ověřuju. V našem případě by se mělo vrátit toto (id a createdAt se bude měnit):
{
id: 7,
date: 2024-10-11T00:00:00.000Z,
exercise: 'Bench Press',
category: 'Chest',
weight: 100,
weightUnit: 'kgs',
reps: 10,
distance: null,
distanceUnit: null,
time: null,
createdAt: 2025-07-04T07:33:49.726Z
}
Pomocí expect(workout).toHaveProperty('id') ověřujeme, že objekt byl skutečně vytvořen a dostal ID. Ostatní expect volání ověřují, že hodnoty byly uloženy správně.
2. Vytvoření neplatného záznamu
Test, který se pokusí vložit záznam s chybějícím polem (např. exercise). Pro úplné pokrytí by bylo třeba provést test pro všechna povinná pole.
it('should fail when required field is missing', async () => {
await expect(
prisma.workout.create({
// @ts-expect-error - testing invalid input (missing exercise)
data: {
date: workoutDay,
category: 'Chest',
weight: 100,
weightUnit: 'kgs',
reps: 10,
},
})
).rejects.toThrow()
})
Tímto kódem - await expect(...).rejects.toThrow() - ověřím, že asynchronní operace vyhodí výjimku. Abych potlačil chybové hlášení z TypeScriptu, že data neobsahují propertu exercise, použil jsem direktivu // @ts-expect-error - testing invalid input (missing exercise).
3. Platný update záznamu
it('should update a workout record', async () => {
const created = await prisma.workout.create({
data: {
date: new Date(),
exercise: 'Squat',
category: 'Legs',
weight: 100,
weightUnit: 'kgs',
reps: 10,
},
})
const updated = await prisma.workout.update({
where: { id: created.id },
data: { exercise: 'Front Squat' },
})
expect(updated.exercise).toBe('Front Squat')
const selectCreatedFromDb = await prisma.workout.findMany({
where: {
id: created.id,
},
})
expect(selectCreatedFromDb).toHaveLength(1)
expect(created.id).toEqual(selectCreatedFromDb[0].id)
expect(created.exercise).not.toEqual(selectCreatedFromDb[0].exercise)
expect(created.category).toEqual(selectCreatedFromDb[0].category)
expect(created.weight).toEqual(selectCreatedFromDb[0].weight)
expect(created.weightUnit).toEqual(selectCreatedFromDb[0].weightUnit)
expect(created.reps).toEqual(selectCreatedFromDb[0].reps)
expect(created.distance).toEqual(selectCreatedFromDb[0].distance)
expect(created.distanceUnit).toEqual(selectCreatedFromDb[0].distanceUnit)
expect(created.time).toEqual(selectCreatedFromDb[0].time)
expect(created.createdAt).toEqual(selectCreatedFromDb[0].createdAt)
})
Po provedení updatu si z databáze znovu načítám aktualizovaný záznam, abych měl jistotu, že změna byla uložena, a že ostatní pole zůstala beze změny.
4. Neplatný update záznamu
it('should fail to update non-existent record', async () => {
await expect(
prisma.workout.update({
where: { id: 99999 },
data: { exercise: 'Something' },
})
).rejects.toThrow()
})
5. Mazání záznamu
it('should delete a workout record', async () => {
const toDelete = await prisma.workout.create({
data: {
date: new Date(),
exercise: 'Death Diving',
category: 'Darwin Award Candidates',
},
})
// check that the entry is stored in db
const selectToDeleteFromDb = await prisma.workout.findMany({
where: {
id: toDelete.id,
},
})
expect(selectToDeleteFromDb[0].id).toEqual(toDelete.id)
const deleted = await prisma.workout.delete({
where: { id: toDelete.id },
})
expect(deleted.exercise).toBe('Death Diving')
// check that the entry is not in db anymore
const selectToDeleteFromDbAfter = await prisma.workout.findMany({
where: {
id: toDelete.id,
},
})
expect(selectToDeleteFromDbAfter).toHaveLength(0)
})
Co bude dál?
V dalším dílu se podívám na testy filtrování, řazení a agregací.

