Зависимости определяются через интерфейсы, а не конкретные типы. Пакет верхнего уровня объявляет интерфейс с нужными методами; нижний уровень реализует его. Внедрение зависимостей - передача реализации (структуры) в конструктор или через опции. Тесты подставляют моки того же интерфейса.