- Published on
Fitnotes (5. díl) - Testy filtrování, řazení a agregací v Prisma modelu
Testy filtrování, řazení a agregací v Prisma modelu
V předchozím dílu jsem implementoval CRUD testy. V tomto článku se zaměřím na složitější operace nad databází: filtrování podle různých podmínek, řazení výsledků a agregační dotazy.
1. Příprava dat pro testy
Před každým testem vymažemedatabázi a připravíme si několik vzorových záznamů, aby testy běžely nad smysluplnými daty.
Například:
- Workout 1: 2024-10-11, Bench Press, Chest, 100 kg
- Workout 2: 2024-10-12, Bench Press, Chest, 110 kg
- Workout 3: 2024-11-01, Squat, Legs, 150 kg
- Workout 4: 2024-12-01, Deadlift, Back, 200 kg
beforeEach(async () => {
await prisma.workout.deleteMany() // vyčistit tabulku před každým testem
await prisma.workout.createMany({
data: [
{
date: new Date('2024-10-11'),
exercise: 'Bench Press',
category: 'Chest',
weight: 100,
weightUnit: 'kgs',
reps: 8,
},
{
date: new Date('2024-10-12'),
exercise: 'Bench Press',
category: 'Chest',
weight: 110,
weightUnit: 'kgs',
reps: 6,
},
{
date: new Date('2024-11-01'),
exercise: 'Squat',
category: 'Legs',
weight: 150,
weightUnit: 'kgs',
reps: 5,
},
{
date: new Date('2024-12-01'),
exercise: 'Deadlift',
category: 'Back',
weight: 200,
weightUnit: 'kgs',
reps: 3,
},
],
})
})
2. Testy filtrování
Filtrování bude v aplikaci častá operace, proto je vhodné pokrýt všechny klíčové scenáře včetně hraničních hodnot (Boundary Value Analysis) a tříd ekvivalence (Equivalence Partitioning). Příklady kódu mají jen ukázat, jak testy rámcově vypadají.
2.1 Filtrování podle data
Scenáře:
- získat všechny tréninky pro konkrétní den
- otestovat hraniční hodnoty:
- dnešní datum (mělo by vrátit prázdný výsledek)
- 1.1.1970 (pravděpodobně prázdný výsledek)
- datum před 1.1.1970
- datum v budoucnosti
it('should return only workouts for a specific date', async () => {
const result = await prisma.workout.findMany({
where: { date: new Date('2024-10-11') },
})
expect(result).toHaveLength(1)
expect(result[0].exercise).toBe('Bench Press')
expect(result[0].weight).toBe(100)
})
2.2 Filtrování podle cviku
Scenáře:
- vyhledávání podle jmena cviku (case-insensitive)
- ošetření mezer a diakritiky (pokud bude v budoucnu potřeba)
- vyhledání neexistujícího cviku
it('should return all workouts for Bench Press (case-insensitive)', async () => {
const result = await prisma.workout.findMany({
where: {
exercise: {
equals: 'bench press',
mode: 'insensitive',
},
},
})
expect(result).toHaveLength(2)
})
3. Testy řazení
Scenáře:
- seřadit tréninky podle data vzestupně
- seřadit tréninky podle data sestupně
it('should sort workouts by date ascending', async () => {
const result = await prisma.workout.findMany({
orderBy: { date: 'asc' },
})
const dates = result.map((r) => r.date.getTime())
const sorted = [...dates].sort((a, b) => a - b)
expect(dates).toEqual(sorted)
})
Pro sestupné řazení bychom změnili orderBy: { date: 'desc' } a otestovali obdobně.
4. Agregační testy
Například nejvyšší zvednutá váha pro daný cvik:
it('should find the max weight for Bench Press', async () => {
const maxWeight = await prisma.workout.aggregate({
_max: { weight: true },
where: { exercise: { equals: 'Bench Press' } },
})
expect(maxWeight._max.weight).toBe(110) // v testu bude vhodné mít tuto hodnotu v proměnné
})
Další možnosti agregací:
- průměrná váha pro cvik (
_avg) - počet tréninků v určitém období (
_count)
5. Kombinace filtrování a řazení
Můžeme testovat například, že při filtrování podle kategorie Chest dostaneme tréninky jen z této kategorie a zároveň budou seřazené podle váhy sestupně.
it('should filter by category Chest and sort by weight desc', async () => {
const result = await prisma.workout.findMany({
where: { category: 'Chest' },
orderBy: { weight: 'desc' },
})
expect(result).toHaveLength(2)
expect(result[0].weight).toBeGreaterThanOrEqual(result[1].weight)
})
Co bude dál?
V dalším dílu se zaměříme na hromadné operace (import CSV) a testování částečně chybných vstupů.

