サードパーティ API をテストする場合、単純かつ宣言的な方法で API を模擬するのは難しいことがよくあります。このパッケージは、特定の順序でスタックからポップされる応答に依存するのではなく、ルーターのような動作を持つ guzzle のカスタム ハンドラーを提供することで、このプロセスを簡素化することを目的としています。
パッケージは、composer 経由でインストールできます。
composer require tomb1n0/guzzle-mock-handler
use GuzzleHttp Client ;
use Tomb1n0 GuzzleMockHandler GuzzleMockHandler ;
// Create a new instance of the mock handler
$ handler = new GuzzleMockHandler ;
// Create a new mock response for '/login', returning ['key' => 'value'] in the body.
// By default responses expect a GET verb, and return a 200 response.
$ loginResponse = ( new GuzzleMockResponse ( ' /login ' ))-> withBody ([
' key ' => ' value '
]);
// Tell the handler that we're expecting this response
$ handler -> expect ( $ loginResponse );
// Create a new Guzzle Handlerstack, passing in our custom handler
$ stack = HandlerStack :: create ( $ handler );
// Finally, create the guzzle client, passing our stack in
$ guzzle = new Client ([ ' handler ' => $ stack ]);
$ response = $ guzzle -> get ( ' /login ' );
// A normal guzzle response object
$ response -> getStatusCode (); // == 200
json_decode (( string ) $ response -> getBody ()); // == ['key' => 'value']
応答を返したリクエストに対してアサーションを実行すると便利な場合があります。おそらく、サードパーティ API にログインするクラスがあり、ユーザー名とパスワードが正しく送信されたことを確認したいと考えています。
$ handler = new GuzzleMockHandler ;
$ loginResponse = ( new GuzzleMockResponse ( ' /login ' ))
-> withMethod ( ' post ' )
-> assertRequestJson ([
' username ' => ' tomb1n0 ' ,
' password ' => ' correct-horse-battery-staple '
]);
// NOTE: If you only care about the username in this case, you can pass in a key as the second parameter to assertRequestJson like so:
/**
* ->assertRequestJson('tomb1n0, 'username');
**/
$ handler -> expect ( $ loginResponse );
$ stack = HandlerStack :: create ( $ handler );
$ guzzle = new Client ([ ' handler ' => $ stack ]);
// Just before the response is actually sent back to guzzle, our handler will assert the request JSON is corect.
$ response = $ guzzle -> post ( ' /login ' , [
' json ' => [
' username ' => ' tomb1n0 ' ,
' password ' => ' correct-horse-battery-staple '
]
]);
注: ->assertRequestHeaders()
を使用してまったく同じアサーションを実行することもできます。これにより、API リクエストにX-API-KEY
ヘッダーなどを確実に含めることができます。
本文やヘッダーをアサートするだけでは不十分な場合があるため、 ->withAssertion()
呼び出してリクエスト オブジェクトとレスポンス オブジェクトを渡し、独自のアサーションを実行できるようにします。
$ handler = new GuzzleMockHandler ;
$ loginResponse = ( new GuzzleMockResponse ( ' /login ' ))
-> withMethod ( ' post ' )
// if you want to perform multiple assertions, you can call -> withAssertion multiple times.
-> withAssertion ( function ( RequestInterface $ request , ResponseInterface $ response ) {
$ this -> assertEquals ( ' super-secure-key ' , $ request -> getHeader ( ' X-API-KEY ' ));
});
$ handler -> expect ( $ loginResponse );
$ stack = HandlerStack :: create ( $ handler );
$ guzzle = new Client ([ ' handler ' => $ stack ]);
$ guzzle -> post ( ' /login ' );
API 呼び出しが正しい順序で行われたことを確認すると便利な場合があります。たとえば、 /users
取得する前に/login
呼び出す必要があるかもしれません。これは、応答に名前を付け、呼び出しが行われた後に順序をアサートすることで実現されます。
$ handler = new GuzzleMockHandler ;
$ loginResponse = ( new GuzzleMockResponse ( ' /login ' ))-> withMethod ( ' post ' );
$ usersResponse = new GuzzleMockResponse ( ' /users ' );
$ handler -> expect ( $ loginResponse , ' login-response ' );
$ handler -> expect ( $ usersResponse , ' users-response ' );
$ stack = HandlerStack :: create ( $ handler );
$ guzzle = new Client ([ ' handler ' => $ stack ]);
$ guzzle -> post ( ' /login ' );
$ guzzle -> get ( ' /users ' );
// Performs a assertsEquals behind the scenes, as the handler keeps track of the order calls were made in.
$ handler -> assertCalledOrder ([
' login-response ' , ' users-response '
]);
場合によっては、テスト内でエンドポイントの呼び出しを 1 回だけ許可したい場合があります。これは、応答オブジェクトで->once()
を呼び出すことで実現できます。
$ handler = new GuzzleMockHandler ;
$ loginResponse = ( new GuzzleMockResponse ( ' /login ' ))
-> withMethod ( ' post ' )
-> once ();
$ handler -> expect ( $ loginResponse );
$ stack = HandlerStack :: create ( $ handler );
$ guzzle = new Client ([ ' handler ' => $ stack ]);
$ response = $ guzzle -> post ( ' /login ' ); // successfull
$ response = $ guzzle -> post ( ' /login ' ); // ResponseNotFound exception is thrown, "No response set for post => /login"
composer test
MIT ライセンス (MIT)。詳細については、ライセンス ファイルを参照してください。
このパッケージは、PHP パッケージ ボイラープレートを使用して生成されました。