Как динамически изменить привязку конкретного класса.
Я пытаюсь протестировать ремесленную команду, которая использует внешний API.
class ConsumeApiCommand extends Command
{
public function __construct(ClientInterface $client)
{
parent::__construct();
$this->client = $client;
}
public function handle()
{
$api_response = $this->client->request('POST', 'http://external.api/resource');
$response = json_decode($api_response);
if(isset($response['error'])) {
$this->error($response['error']);
} else {
$this->status($response['status']);
}
}
}
В настоящее время; Я могу подделать конкретный класс в моих тестах.
class FakeServiceProvider extends AppServiceProvider
{
public function register(): void
{
$this->app->bind(ClientInterface::class, function () {
return new class implements ClientInterface {
public function request($method, $uri, $headers = [], $body = [])
{
return json_encode(['status' => "You've reached us."]);
}
};
});
}
}
Passing.
public function test_can_consume_api_if_authenticated()
{
$this->artisan('consume:api')
->expectsOutput("You've reached us.")
->assertExitCode(0);
}
В противном случае; возвращает изначально связанный класс ответа You've reached us.
public function test_cant_consume_api_if_not_authenticated()
{
$this->app->bind(ClientInterface::class, function () {
return new class implements ClientInterface {
public function request($method, $uri, $headers = [], $body = [])
{
return json_encode(['error' => "Unauthorized."]);
}
};
});
$this->artisan('consume:api')
->expectsOutput("Unauthorized.")
->assertExitCode(0);
}
Можно ли таким образом добиться желаемого поведения? Или привязки контейнера службы не могут измениться в течение срока действия запроса?