結論
Httpのファサードをテストしたい時は下記のようにする
被テスト側
HogeController.php
<?php
namespace App\Http\Controllers\Api\V1;
use Illuminate\Support\Facades\Http;
class HogeController extends Controller
{
public function get()
{
$response = Http::get('http://example.com/');
return response()->json($response->json());
}
}
→そのまま実行すると、404エラーになる
Routeは割愛
テスト側
※PestPHPで記載しています
HogeTest.php
<?php
use App\Http\Controllers\Api\V1\HogeController;
use Illuminate\Support\Facades\Http;
it('getテスト', function () {
$response = [
'message' => 'fake!'
];
Http::fake([
"http://example.com/" => Http::response($response, 200),
]);
$controller = new HogeController();
$response = $controller->get();
expect(json_decode($response->getContent(), true))
->toEqual(
[
'message' => 'fake!'
]
)
->and($response->status())
->toBe(200);
});
HogeTest
を実行すると(./vendor/bin/pest --filter=HogeTest
)
->message: fake!
という文字列がレスポンスコード200
で返却される
$responseの中身
array:1 [
"message" => "fake!"
]
解説
通常は下記のように処理が進む
Route::get('/', 'HogeController@get');
-> HogeController::get()
ー> Http::get('http://example.com(外部サービス)')
-> Http::get()した結果を返す
テスト時はFakeを使わないと下記のようになる
HogeTest
-> HogeController::get()
ー> Http::get('http://example.com(外部サービス)')
-> Http::get()した結果を返す
問題点
-
http://example.com
が実際にアクセス可能でないとテストできない - テストしたいデータがいつでも返ってくるようなサーバーでないと、再現できないテストケースが存在してしまう
改善
テスト時は下記のようにする
HogeTest
-> HogeController::get()
ー> Http::fake()
-> Http::fake()の結果を返す
Http::fakeは特定URLに対して、特定のレスポンスをさせる便利なメソッド。
Httpはファサードであるため、その後にファサードを呼ぶクラスをインスタンス化し、実行することでfakeが有効になる
つまり、本番コードはそのままに、テスト時だけさまざまなレスポンスをテスト可能です!