Что вы можете сделать, это зарегистрировать ApiModel
в контейнере с помощью поставщика услуг.
Для этого создайте нового поставщика услуг - позвоните ему, например, ApiServiceProvider
php artisan make:provider ApiServiceProvider
Я предполагаю, что вы используете экземпляр ApiModel
только в нескольких указанных c местах, поэтому откладываете его регистрацию до тех пор, пока он действительно не понадобится.
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Support\DeferrableProvider;
class ApiServiceProvider extends ServiceProvider implements DeferrableProvider
{
public function register(): void
{
$this->app->singleton(APIModel::class, function () {
return new APIModel;
});
}
public function provides(): array
{
return [APIModel::class];
}
}
Теперь обновите ваш пост метод, внедрив в него экземпляр ApiModel
в качестве второго аргумента
class MyController extends Controller
{
public function post(Request $request, APIModel $client)
{
$apiResponse = $client->GenId();
// Other process such as get data from database, validate data
return view(...);
}
}
Далее в своем тесте замените привязку на макет ApiModel
$this->mock(APIModel::class, function ($mock) {
$mock->shouldReceive('GenId')->once()->andReturn(1);
});
Над I Я указываю, что метод GenId
должен возвращать 1
, но вы можете изменить его на то, что вам нужно.
Подробнее о насмешках: Насмешливые объекты
В качестве альтернативы вы можете просто использовать анонимный класс и заменить экземпляр ApiModel
на контейнере на него
$this->instance(APIModel::class, new class {
public function GenId()
{
return 1;
}
});
Если вы хотите, чтобы оставшаяся функциональность ApiModel
работала полностью и только замените GenId
метод, тогда вы можете расширить его
$this->instance(APIModel::class, new class extends ApiModel {
public function GenId()
{
return 1;
}
});
Надеюсь, это поможет.