图书馆:" aws / aws-sdk-php":" 2。*"
PHP版本:PHP 5.4.24(cli)
composer.json
{
"require": {
"php": ">=5.3.1",
"aws/aws-sdk-php": "2.*",
...
},
"require-dev": {
"phpunit/phpunit": "4.1",
"davedevelopment/phpmig": "*",
"anahkiasen/rocketeer": "*"
},
...
}
我们制作了一个AwsWrapper来获取功能性操作:uploadFile,deleteFile ...
您可以阅读课程,依赖注入进行单元测试
专注于构造函数和内部$ this-> s3Client-> putObject(...)调用uploadFile函数。
<?php
namespace app\lib\modules\files;
use Aws\Common\Aws;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use core\lib\exceptions\WSException;
use core\lib\Injector;
use core\lib\utils\System;
class AwsWrapper
{
/**
* @var \core\lib\Injector
*/
private $injector;
/**
* @var S3Client
*/
private $s3Client;
/**
* @var string
*/
private $bucket;
function __construct(Injector $injector = null, S3Client $s3 = null)
{
if( $s3 == null )
{
$aws = Aws::factory(dirname(__FILE__) . '/../../../../config/aws-config.php');
$s3 = $aws->get('s3');
}
if($injector == null)
{
$injector = new Injector();
}
$this->s3Client = $s3;
$this->bucket = \core\providers\Aws::getInstance()->getBucket();
$this->injector = $injector;
}
/**
* @param $key
* @param $filePath
*
* @return \Guzzle\Service\Resource\Model
* @throws \core\lib\exceptions\WSException
*/
public function uploadFile($key, $filePath)
{
/** @var System $system */
$system = $this->injector->get('core\lib\utils\System');
$body = $system->fOpen($filePath, 'r');
try {
$result = $this->s3Client->putObject(array(
'Bucket' => $this->bucket,
'Key' => $key,
'Body' => $body,
'ACL' => 'public-read',
));
}
catch (S3Exception $e)
{
throw new WSException($e->getMessage(), 201, $e);
}
return $result;
}
}
测试文件将我们的Injector和S3Client实例作为PhpUnit MockObject。要模拟S3Client,我们必须使用Mock Builder禁用原始构造函数。
模拟S3Client:
$this->s3Client = $this->getMockBuilder('Aws\S3\S3Client')->disableOriginalConstructor()->getMock();
配置内部putObject调用(使用putObject抛出S3Exception进行测试的情况,但是我们在$ this-&gt; returnValue($ expected)中遇到了同样的问题。
初始化测试类并配置sut:
public function setUp()
{
$this->s3Client = $this->getMockBuilder('Aws\S3\S3Client')->disableOriginalConstructor()->getMock();
$this->injector = $this->getMock('core\lib\Injector');
}
public function configureSut()
{
return new AwsWrapper($this->injector, $this->s3Client);
}
不工作代码:
$expectedArray = array(
'Bucket' => Aws::getInstance()->getBucket(),
'Key' => $key,
'Body' => $body,
'ACL' => 'public-read',
);
$this->s3Client->expects($timesPutObject)
->method('putObject')
->with($expectedArray)
->will($this->throwException(new S3Exception($exceptionMessage, $exceptionCode)));
$this->configureSut()->uploadFile($key, $filePath);
当我们执行测试函数时,注入的S3Client不会抛出异常或返回预期值,总是返回NULL。
使用xdebug,我们已经看到S3Client MockObject配置正确,但不会按照will()配置的方式工作。
A&#34;解决方案&#34; (或者一个糟糕的解决方案)可能正在做一个S3ClientWrapper,这只会将问题转移到其他无法通过模拟进行单元测试的类。
有什么想法吗?
UPDATE 使用xdebug配置MockObject的屏幕截图:
答案 0 :(得分:12)
以下代码按预期工作和传递,因此我认为您不会遇到由PHPUnit或AWS SDK引起的任何限制。
<?php
namespace Aws\Tests;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use Guzzle\Service\Resource\Model;
class MyTest extends \PHPUnit_Framework_TestCase
{
public function testMockCanReturnResult()
{
$model = new Model([
'Contents' => [
['Key' => 'Obj1'],
['Key' => 'Obj2'],
['Key' => 'Obj3'],
],
]);
$client = $this->getMockBuilder('Aws\S3\S3Client')
->disableOriginalConstructor()
->setMethods(['listObjects'])
->getMock();
$client->expects($this->once())
->method('listObjects')
->with(['Bucket' => 'foobar'])
->will($this->returnValue($model));
/** @var S3Client $client */
$result = $client->listObjects(['Bucket' => 'foobar']);
$this->assertEquals(
['Obj1', 'Obj2', 'Obj3'],
$result->getPath('Contents/*/Key')
);
}
public function testMockCanThrowException()
{
$client = $this->getMockBuilder('Aws\S3\S3Client')
->disableOriginalConstructor()
->setMethods(['getObject'])
->getMock();
$client->expects($this->once())
->method('getObject')
->with(['Bucket' => 'foobar'])
->will($this->throwException(new S3Exception('VALIDATION ERROR')));
/** @var S3Client $client */
$this->setExpectedException('Aws\S3\Exception\S3Exception');
$client->getObject(['Bucket' => 'foobar']);
}
}
如果您只想模拟响应并且不关心模拟/存根对象,也可以使用Guzzle MockPlugin。