问题
I want to test an HTTP route in laravel. The action function of the URL calls a helper function, which calls an external API. How can I mock the external API call while testing?
public function actionFunction(){
$helper = new HelperClassHelper();
return Response::json($helper->getNames());
}
Here, the getNames() function makes an external API call. How do I mock it?
回答1:
You can add the HelperClassHelper as a dependency in the action, and then you are able to mock it in the test:
public function actionFunction(HelperClassHelper $helper){
return Response::json($helper->getNames());
}
In the test:
$this->app->bind(HelperClassHelper::class, function () { /* return mock */ });
回答2:
let me made this simple.
follow this step :
1.) add service app/Services/MyService/HttpClient.php
. in this case i'm using postman 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.) add controller 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.) add test file 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.) add json file tests/files/success.json
for fake response :
{
"mock" : "yes"
}
来源:https://stackoverflow.com/questions/52309653/how-can-i-mock-external-api-during-testing-in-laravel-5