Задача курса

Python: Реализуй TaskRepository и напиши тест с stub-репозиторием

Курс «Python для продвинутых: ООП, типизация и тестирование» · урок «Repository: отделение хранения данных от бизнес-логики»

Условие

Реализуй TaskRepository и напиши тест с stub-репозиторием

Тебе нужно реализовать класс TaskRepository, который хранит задачи в JSON-файле, и написать тест бизнес-функции complete_task с использованием stub-репозитория.

Что уже дано

Проверяющая система скрыто создаёт:

  • файл tasks.json на диске с тестовыми данными;
  • вспомогательные функции load_json(path) и save_json(path, data) в пространстве имён (они уже доступны без импорта).

Эти имена доступны в том же процессе и пространстве имён, где выполняется твой код:

  • load_json — читает JSON из файла по Path, возвращает list[dict];
  • save_json — записывает list[dict] в JSON-файл по Path;
  • tasks_path — объект Path, указывающий на tasks.json.

Что нужно сделать

Определи на верхнем уровне:

  1. @dataclass class Task с полями:
  • id: int
  • title: str
  • done: bool
  1. class TaskRepository с методами:
  • __init__(self, path: Path) -> None — сохраняет путь в self._path;
  • load(self) -> list[Task] — читает файл через load_json(self._path) и возвращает список объектов Task (используй Task(**row) для каждой строки);
  • save(self, tasks: list[Task]) -> None — сериализует список через asdict и записывает через save_json(self._path, rows).

Внутри load и save не должно быть бизнес-логики: только чтение/запись и преобразование между словарями и объектами.

  1. def complete_task(repo, task_id: int) -> None — бизнес-функция, которая:
  • вызывает repo.load();
  • находит задачу с нужным id и устанавливает done = True;
  • вызывает repo.save(tasks).

Функция не должна содержать вызовы load_json, save_json, open или любых других файловых операций напрямую.

  1. class StubTaskRepository — stub для тестов:
  • __init__(self, tasks: list[Task]) — сохраняет список в self._tasks;
  • load(self) -> list[Task] — возвращает self._tasks;
  • save(self, tasks: list[Task]) -> None — сохраняет переданный список в self._tasks.
  1. Верхнеуровневый код теста — создай StubTaskRepository с тремя задачами (id=1 done=False, id=2 done=False, id=3 done=True), вызови complete_task(stub_repo, 2) и сохрани результат stub_repo.load() в переменную result_tasks.

Ввод и вывод

stdin не используется. Печатать через print в stdout ничего не нужно.

Проверяющая система после выполнения твоего кода читает следующие верхнеуровневые имена:

  • Task — класс-dataclass;
  • TaskRepository — класс репозитория;
  • complete_task — бизнес-функция;
  • StubTaskRepository — stub-класс;
  • result_tasks — список объектов Task после вызова complete_task на stub.

Пример использования

repo = StubTaskRepository([
    Task(1, "A", False),
    Task(2, "B", False),
])
complete_task(repo, 2)
print([(task.id, task.done) for task in repo.load()])

Результат:

[(1, False), (2, True)]

Попробуйте решить

РешениеPython
Без регистрации · результат не сохраняется
Python: Реализуй TaskRepository и напиши тест с stub-репозиторием