庫: 「AWS/AWS-SDK-PHP」: 「2 *」
PHP版本:PHP 5.4.24(CLI)PHPUnit的 - 模擬S3Client都不盡如人意
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,但我們有同樣的問題,這 - $>的returnValue($預期)
。要初始化測試類和配置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()那樣配置。
一個「解決方案」(或一個糟糕的解決方案)可能會做一個S3ClientWrapper,這隻會將問題移動到其他類,不能單元測試與模擬。
有什麼想法?
UPDATE 截圖上配置MockObject與Xdebug的:
With - > setMethods(['putObject'])工作正常!謝謝!! –