Awsクライアントのラッパークラスを作ると結構便利
以前、こんなライブラリつくった。
Aws のクライアントクラスをシュパッと作れるやつ。
AwsClientManager for PHP というライブラリを作った - Lazuli
AwsSDK はそれ単体だけだとなかなか使いづらくテストに利用しにくい。
ラッパークラスを作ってやるとテストが容易になるかもと気付いてやってみたら結構いい感じに収束できた。
たとえば、何かをアップロードするようなクラスを作った場合。
<?php class Uploader { private $S3; public function setS3 ($S3) { $this->S3 = $S3; } public function upload ($from_path, $to_path) { $result = $this->S3->putObject([ 'Bucket' => 'bucket_name', 'Key' => $to_path, 'Body' => \Guzzle\Http\EntityBody::factory(fopen($from_path, 'r')) ]); return $result; } }
色々端折ってるけど upload メソッドにパスを渡してやると S3 にアップロードできるよ!って感じ。
次に S3 用のラッパークラス。
<?php class S3 { private $client; public function __construct (\Aws\Ec2\Ec2Client $client) { $this->client = $client; } public function putObject ($args) { try { $this->client->putObject($args); } catch (\Exception $e) { throw $e; } return true; } }
Ec2Client クラスに委譲してるだけなんだけどコンストラクタでクライアント渡すようにしてる。
この部分をモックにしてあげればテストに使えるようになる。
<?php class UploaderTest extends PHPUnit_Framework_TestCase { private $uploader; private $S3_mock; public function setUp () { $this->uploader = new Uploader(); $this->S3_mock = $this->getMock('....'); } /** * @test */ public function upload () { $this->uploader->setS3($this->S3_mock); $result = $this->uploader->upload('/tmp/foo.txt', 'foo.txt'); $this->assertTrue($result); } }
setS3 にモックを渡してるから AwsSDK のクラスがどうなっていようと気にすることなくテストが出来る。
実コードのときは正しいクライアントクラスを渡してあげればよい。
AwsClientManager for PHP というライブラリを作った - Lazuli
これを使うのならば、
<?php use S3; use Acm\Acm; $from_path = '/tmp/foo.txt'; $to_path = 'foo.txt'; $S3 = new S3(Acm::getS3()); $uploader = new Uploader->setS3($S3); $uploader->upload($from_path, $to_path);
どやぁ。