# Тесты `ExerciseRepository` и `ExerciseReplacementRepository` (слой Src) > Репозитории `Server.WatchBody.Core.Dal.Src.Repository`: > IExerciseRepository / ExerciseRepository, IExerciseReplacementRepository / ExerciseReplacementRepository > (правила — c-dal; unit-тесты без БД — c-tst, d-tst). ## Методы → функции БД | Репозиторий | Метод | Функция БД | |---|---|---| | Exercise | `Insert(Exercise)` → Guid | `src.exercise_insert` | | Exercise | `Update(Exercise)` → int | `src.exercise_update` | | Exercise | `Delete(int athleteId, Guid exerciseId)` → int | `src.exercise_delete` | | Exercise | `Select(ExerciseFilter?)` → IEnumerable | `src.exercise_select` | | Exercise | `Get(int athleteId, Guid exerciseId)` → Exercise? | `src.exercise_get` | | ExerciseReplacement | `Insert(int athleteId, Guid exerciseId, Guid replacementId)` → int | `src.exercise_replacement_insert` | | ExerciseReplacement | `Delete(int athleteId, Guid exerciseId, Guid replacementId)` → int | `src.exercise_replacement_delete` | `ExerciseFilter`: `Name` (string?), `GroupId` (int?), `IsBase` (bool?), `IsActive` (bool?); NULL — не применяется. ## Механика теста (общая) `ConnectionStringTest` (d-tst-11); один DataTable = один конвертер; замены приходят денормализованно колонкой `replacement_ids` (jsonb) — конвертер разбирает её в `ReplacementIds`. ## Заготовки (DataTable) Таблица ответа `exercise_*`: id:Guid, athlete_id:int, name:string, group_id:int, is_base:bool, is_active:bool, replacement_ids:string (jsonb). Строки-фикстуры: `e1` — TEST-жим, группа 1, активное, replacement_ids='[]'; `e2` — TEST-тяга, группа 2, активное, replacement_ids='[""]'. ## Тесты: `Insert` (Exercise) | № | Тип | Условие | Ожидаемый результат | |---|---|---|---| | 1 | основной | e1; scalar = Guid e1.Id | Insert→Guid; параметры p_athlete_id, p_id, p_name, p_group_id, p_is_base | ## Тесты: `Update` (Exercise) | № | Тип | Условие | Ожидаемый результат | |---|---|---|---| | 1 | основной | e1 с новым именем; scalar = 1 | 5 параметров (все поля, db-m-8); ReplacementIds не передаётся | ## Тесты: `Delete` (Exercise) | № | Тип | Условие | Ожидаемый результат | |---|---|---|---| | 1 | основной | scalar = 1 | Delete→1; параметры p_athlete_id, p_id | ## Тесты: `Select` (Exercise) | № | Тип | Условие | Ожидаемый результат | |---|---|---|---| | 1 | основной | таблица [e1, e2]; фильтр IsActive=true | 2 сущности; у e2 ReplacementIds = 1 Guid | | 2 | граничный | пустая таблица; фильтры NULL | пустая коллекция; NULL-фильтры = DBNull | ## Тесты: `Get` (Exercise) | № | Тип | Условие | Ожидаемый результат | |---|---|---|---| | 1 | основной | таблица [e2] | сущность с ReplacementIds = 1 Guid | | 2 | граничный | пустая таблица | null | ## Тесты: `Insert` (ExerciseReplacement) | № | Тип | Условие | Ожидаемый результат | |---|---|---|---| | 1 | основной | scalar = 1 | 3 параметра: p_athlete_id, p_exercise_id, p_replacement_id | ## Тесты: `Delete` (ExerciseReplacement) | № | Тип | Условие | Ожидаемый результат | |---|---|---|---| | 1 | основной | scalar = 1 | 3 параметра; возврат 1 |