Есть такая известная парадигма в ООП — сервис-контейнеры. Суть её в том, чтобы получать реализацию того или иного сервиса, который тебе зачем-то нужен, из некоего контейнера. То есть не задумываясь о деталях, о том, что это за класс и т.д. Обращаешься к контейнеру — а контейнер сам определит, что надо, и вернет нужный сервис. Очевидно, если заранее не знаешь, о чем речь, из такого пояснения ни фига толком не ясно. Обычно эти пояснения иллюстрируются примерами. В доках Ларавела, скажем, используется пример EventPusher-а и его реализации через Redis.
Слабое место подобных примеров, на мой взгляд, в том, что для начинающего разработчика, не очень знакомого с концепцией контейнера и dependency injection, идея замены одной реализации сервиса на другую не очень близка. В голову сразу приходит, что у меня-то сейчас один класс используется — вот этот. Когда надо будет другой, тогда и контейнер сделаю, а пока буду явно обращаться к данному классу. И это, как мне кажется, вполне нормальный ход мыслей.
Поэтому попробую привести чуть более живой (на мой взгляд, опять же) пример, связанный с тестами, показывающий, в каком случае нам понадобится замена реализации сервиса прямо сейчас, а не когда-нибудь потом.
Допустим, вы в своих проектах практикуете TDD. И у вас, помимо всех остальных тестов, проверяющих всё на свете, есть тест создания какой-нибудь модели через API Post, или просто через форму. И вот внезапно вам понадобилось подцепить на эту форму проверку reCAPTCHA против спаммеров. Реализовать саму логику работы во фронте (на Vue.js) и проверку полученного токена в бэке — нетрудно (вот пример).
А вот тест создания модели (и все связанные с этим роутом/формой тесты) — немедленно поломаются. Потому что где вы возьмете валидный ключ капчи для проверки, если он в тестовом режиме не прилетает из фронта?
Можно было бы попытаться организовать прохождение капчи для бэк-энд тестов (хотя я не совсем понял, как это именно в случае reCAPTCHA сделать). Но: — от этого нет пользы помимо тестирования; — у нас нет задачи тестировать гугл-капчу в каждом тесте бэкенда, который проверяет работу методов post/put у каждой защищенной капчей формы; — для тестирования внешнего сервиса достаточно одного теста интеграции — что мы верно всё подключили — а остальное есть забота разработчика внешнего сервиса; — если каждый тест формы будет проверять ключ капчи через сервис гугла, тесты внезапно станут значительно дольше работать.
В общем, представляется что не нужно это делать. Вот тут-то и возникает необходимость в подмене живой капчи — фейковой. И это как раз неплохо иллюстрирует концепцию сервис-контейнеров и внедрения зависимостей. Далее — код.