Я все еще в процессе изучения Laravel и Dependency Injection. Я понимаю концепцию, но я не знаю, как смоделировать зависимость в этом конкретном случае:
MyController.php
use Illuminate\Routing\Controller;
use MyPackage\Services\ServiceInterface;
class MyController extends Controller{
protected $service;
public function __construct(ServiceInterface $service)
{
$this->service = $service;
}
}
MyServiceProvider.php
use Illuminate\Support\ServiceProvider;
class MyServiceProvider extends ServiceProvider{
public function register()
{
$this->app->bind('MyPackage\Services\ServiceInterface', function ($app) {
return new MyPackage\Services\ConcreteService(['key'=>'123'], $app->make('GuzzleHttp\Client'));
});
}
}
Итак, как вы можете видеть, у меня есть контроллер, который требует экземпляр ServiceInterface. Этот экземпляр разрешается в ServiceProvider. Конструктор ConcreteService требует, чтобы клиент выполнил Http-запрос к API. Этот Http разрешается контейнером Service (это будет экземпляр Guzzle).
Теперь, как я могу издеваться над этим экземпляром Guzzle на моих тестах?
Идеальный результат — сделать что-то вроде этого:
MyTest.php
...
$this->post(route('routeToActionInMyController'), $params);
Итак, в моих тестах мне просто нужно найти маршрут, который будет использовать определенный метод MyController.php, но мне не нужен «настоящий» экземпляр Guzzle. Мне просто нужно смоделировать ответ на тест, если MyController ведет себя ожидаемым образом (и правильно хранит вещи в базе данных).
Как я могу дать команду Service Container вводить Mocked-объект только во время тестов? Или я делаю это совершенно неправильно?
Любая помощь будет оценена.
заранее спасибо
В вашем тестовом классе:
class TestingSomething extends TestCase {
protected function setUp() {
parent::setUp();
$mockServiceInterface = $this->getMockBuilder(ServiceInterface::class)->getMock();
$this->app->instance(ServiceInterface::class,$mockServiceInterface);
}
public function testPostToRoute() {
$this->post(route('routeToActionInMyController'), $params);
}
}
Это должно заменить то, что уже связано в сервисном контейнере с этим фиктивным экземпляром.
Обратитесь к Руководство по PHPUnit в главе 9. Тест удваивается за то, что вы можете сделать с макетом строителя и получившимися макетами.
Других решений пока нет …