Skip to content

Instantly share code, notes, and snippets.

@proshunsuke
Created September 25, 2017 10:21
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save proshunsuke/76d57c219b7c8c2d6e2cb690d0850975 to your computer and use it in GitHub Desktop.
php-vcrを使いやすくするためのtrait
<?php
namespace src\Tests\Support;
use VCR\Request;
use VCR\VCR;
/**
* Trait VcrTrait
*/
trait VcrTrait
{
/**
* php-vcrを簡単に使えるようにするもの
* @see https://github.com/php-vcr/php-vcr
*
* 使い方
*
* 引数のcallbackにAPI通信を伴う処理を入れて、cassettePathとcassetteName(デフォルトではymlファイル)を指定する
* そうすると'cassettePath/cassetteName'が作られ、同じリクエスト内容であれば次回以降はこのファイルが参照される
*
* 例
*
* use VcrTrait;
* $response = $this->useCassette(function () {
* return $apiClient->apiRequest();
* }, 'cassettePath', 'cassette_name.yml');
*
* 注意
*
* $requestMatchersにheadersが指定されていた場合は実行環境に依存する値を気にしないようにしている
* 個々の環境でcurlのバージョンなどが異なる等の理由でテストが落ちることがあるため
*
* @param $callback
* @param $cassettePath
* @param $cassetteName
* @param string $storage
* @param array $libraryHooks
* @param array $requestMatchers
* @param null $mode
*
* @return mixed
*/
private function useCassette(
$callback,
$cassettePath,
$cassetteName,
$storage = 'yaml',
array $libraryHooks = ['curl', 'stream_wrapper'],
array $requestMatchers = [
'method',
'url',
'headers',
'host',
'body',
'post_fields',
'query_string'
],
$mode = null
) {
if (!is_dir($cassettePath)) {
mkdir($cassettePath);
}
VCR::configure()->setCassettePath($cassettePath);
VCR::configure()->setStorage($storage);
VCR::configure()->enableLibraryHooks($libraryHooks);
$requestMatchers = $this->getRequestMatchersIgnoredDependence($requestMatchers);
VCR::configure()->enableRequestMatchers($requestMatchers);
if ($mode) {
VCR::configure()->setMode($mode);
}
VCR::turnOn();
VCR::insertCassette($cassetteName);
$result = call_user_func($callback);
VCR::eject();
VCR::turnOff();
return $result;
}
/**
* headerのmatch時に実行環境に依存する項目を除く
* 実行環境に依存しないheadersが合っていた場合にtrueを返す
*
* @return \Closure
*/
private function matchHeadersIgnoredDependence()
{
return function (Request $first, Request $second) {
$firstHeadersIgnoredUA = $first->getHeaders();
unset($firstHeadersIgnoredUA['User-Agent']);
unset($firstHeadersIgnoredUA['Authorization']);
$secondHeadersIgnoredUA = $second->getHeaders();
unset($secondHeadersIgnoredUA['User-Agent']);
unset($secondHeadersIgnoredUA['Authorization']);
return array_filter($firstHeadersIgnoredUA) === array_filter($secondHeadersIgnoredUA);
};
}
/**
* $requestMatchersにheadersが含まれていた場合は、実行環境に依存しないheadersを対象にする
* @see http://php-vcr.github.io/documentation/configuration/#request-matching
*
* @param array $requestMatchers
*
* @return array
*/
private function getRequestMatchersIgnoredDependence(array $requestMatchers)
{
if (in_array('headers', $requestMatchers)) {
$requestMatchers = array_diff($requestMatchers, ['headers']);
VCR::configure()->addRequestMatcher('headers_ignore_ua_matchers', $this->matchHeadersIgnoredDependence());
$requestMatchers[] = 'headers_ignore_ua_matchers';
}
return $requestMatchers;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment