Я хочу протестировать HTTP-маршрут в laravel. Функция действия URL-адреса вызывает вспомогательную функцию, которая вызывает внешний API. Как я могу имитировать внешний вызов API во время тестирования?
public function actionFunction(){
$helper = new HelperClassHelper();
return Response::json($helper->getNames());
}
Здесь функция getNames () выполняет внешний вызов API. Как мне поиздеваться?
Вы можете добавить HelperClassHelper в качестве зависимости в действие, и тогда вы сможете имитировать его в тесте:
public function actionFunction(HelperClassHelper $helper){
return Response::json($helper->getNames());
}
В тесте:
$this->app->bind(HelperClassHelper::class, function () { /* return mock */ });
@SreekanthMK, когда вы добавляете HelperClassHelper
в метод, он разрешается из контейнера (внедрение зависимостей). Итак, в тесте вы можете использовать $this->app->bind...
, который заменит настоящий класс в контейнере на макет.
Я добавил это в тест, $ this-> app-> bind (InfusionsoftHelper :: class, function () {return "this is a mock";}); Но все равно никаких изменений.
позвольте мне сделать это просто.
выполните этот шаг:
1.) добавить сервис app/Services/MyService/HttpClient.php
. в этом случае я использую api почтальона.
namespace App\Services\MyService;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
class HttpClient
{
public function send(array $payload) : Response
{
return app(Client::class)
->request('POST', 'https://postman-echo.com/post', $payload);
}
}
2.) добавить контроллер app/Http/Controllers/TestController.php
namespace App\Http\Controllers;
use App\Services\MyService\HttpClient;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class TestController extends Controller
{
public function index(Request $request)
{
$response = app(HttpClient::class)->send($request->toArray());
$data = json_decode( $response->getBody()->getContents(),true);
return response()->json(
$data,
$response->getStatusCode()
);
}
}
3.) добавить тестовый файл tests/Feature/SampleTest.php
namespace Tests\Feature;
use App\Services\MyService\HttpClient;
use GuzzleHttp\Psr7\Response;
use Illuminate\Support\Facades\File;
use Tests\TestCase;
class SampleTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
//do awesome thing
}
public function testExample()
{
$this->mock(HttpClient::class, function ($mock) {
return $mock->shouldReceive('send')
->once()
->andReturn(new Response(
$status = 200,
$headers = [],
File::get(base_path('tests/files/success.json'))
));
});
$data = [
'mock' => 'no'
];
$response = $this->call('post','/test', $data);
$response->assertExactJson(['mock' => 'yes']);
$response->assertStatus(200);
}
}
4.) добавьте json-файл tests/files/success.json
для фальшивого ответа:
{
"mock" : "yes"
}
Спасибо за ответ. Не могли бы вы объяснить и насмешливую часть? Я делаю это впервые и для меня это немного сложно.