Thư viện: "AWS/AWS-sdk-php": "2. *"
PHP phiên bản: PHP 5.4.24 (cli)PHPUnit - Mock S3Client không hoạt động tốt
composer.json
{
"require": {
"php": ">=5.3.1",
"aws/aws-sdk-php": "2.*",
...
},
"require-dev": {
"phpunit/phpunit": "4.1",
"davedevelopment/phpmig": "*",
"anahkiasen/rocketeer": "*"
},
...
}
Chúng tôi đã tạo AwsWrapper để nhận các hành động chức năng: uploadFile, deleteFile ...
Bạn có thể đọc lớp học, với tiêm phụ thuộc để được kiểm tra đơn vị.
Tập trung vào hàm tạo và bên trong $ this-> s3Client-> putObject (...) gọi hàm 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;
}
}
Tệp thử nghiệm có trường hợp Injector và S3Client là PhpUnit MockObject. Để giả sử S3Client, chúng ta phải vô hiệu hóa hàm khởi tạo ban đầu bằng Trình dựng Mock.
Để thử S3Client:
$this->s3Client = $this->getMockBuilder('Aws\S3\S3Client')->disableOriginalConstructor()->getMock();
Để cấu hình bên trong putObject gọi (trường hợp để kiểm tra với putObject ném S3Exception, nhưng chúng tôi có cùng một vấn đề với $ this-> returnValue ($ dự kiến)
. init kiểm tra lớp và cấu hình sut: mã
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);
}
Không làm việc:
$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);
Khi chúng tôi thực hiện chức năng thử nghiệm của chúng tôi, S3Client được tiêm không ném ngoại lệ hoặc trả về giá trị mong đợi, luôn trả về NULL.
Với xdebug, chúng ta đã thấy rằng S3Client MockObject được cấu hình đúng nhưng không hoạt động như được cấu hình theo ý muốn().
Một "giải pháp" (hoặc một giải pháp xấu) có thể đang thực hiện S3ClientWrapper, điều này sẽ chỉ di chuyển vấn đề đến lớp khác mà không thể là đơn vị được thử nghiệm với mocks.
Bất kỳ ý tưởng nào?
CẬP NHẬT Ảnh chụp màn hình trên configure MockObject với Xdebug:
Với -> setMethods (['putObject']) đang hoạt động OK! Cảm ơn!! –