PHPUnit — Насмешка над объектом класса переноса Guzzle / S3 с помощью методов Promise

У меня есть функция, которая выглядит следующим образом:

public function downloadProjectFolder($projectId, $taskToken){

// Download the project directory if it isn't on the server
if(is_dir('/path/to/folder/') === false){
$manager = $this->instantiateS3TransferObject($projectId, $taskToken);
$promise = $manager->promise();
$promise->wait();
}
else{
return 'Project Folder Already Exists';
}

}

Приведенный выше метод загружает папку на мой сервер из AWS S3, если она еще не существует на локальном компьютере. Реальный объект S3 Transfer (из библиотеки AWS PHP SDK V3 — который сам по себе в основном абстрагируется от Guzzle PHP) создается с помощью следующей функции:

private function instantiateS3TransferObject($projectId, $taskToken){

$lastDatetime = time();
return new \Aws\S3\Transfer($this->myS3ClientObject, 's3://mys3bucket/destination/url',
'/path/to/local/directory/', array(
'base_dir' => 'destination/url',
'before' => function()use($projectId, $taskToken, &$lastDatetime){
$currentDatetime = time();
if(($currentDatetime - $lastDatetime) >= 30){
$postParams = array(
'project_id' => $projectId,
'task_token' => $taskToken
);
$this->curl->post($postParams, 'http://url/endpoint');
$lastDatetime = $currentDatetime;
}
}
)
);

}

Вышеприведенное, по сути, запускает загрузку моей папки и выполняет выборочную конечную точку каждые 30 секунд асинхронно.

Как бы я издеваться \Aws\S3\Transfer объект в этом случае, так что он включает в себя promise() метод по возвращении, и этот метод в свою очередь возвращает wait() метод?

0

Решение

Не так много вы можете сделать с time так как это нативная функция и не может быть посмешищем. Вы можете слегка изменить его для тестируемости на что-то вроде:

class TimeGetter
{
public function getTime()
{
return time();
}
}

а затем использовать как

$currentDatetime = $this->timeGetter->getTime();
// instead of $currentDatetime = time();

Таким образом, вы можете высмеять его позже и вернуть в любое время, когда вам нужно проверить свою функциональность.

Ни вы не можете создать макет для \Aws\S3\Transfer, поскольку вы явно создаете новый экземпляр в instantiateS3TransferObject,

Для остальной части кода вам нужно будет смоделировать оба Guzzle а также curl, Очень грубое приближение, основанное на фрагменте кода в вопросе:

// First Guzzle, but order doesn't matter:
$mock = new MockHandler([
// first expected request
function($_self, RequestInterface $request, array $options) {
// assert $request values meet expectations
// and return response or exception you expect from S3
return new Response(200, ['X-Foo' => 'Bar']);
},
// second expected request, if any, is either instance of Response, Exception, or a function which returns one of them
// third expected request, etc...
]);

$handler = HandlerStack::create($mock);
// then pass it to the class under test
// assuming it is public:
$cut->myS3ClientObject = new Client(['handler' => $handler]);

// Now curl:
$curlMock = $this->getMockBuilder('\whatever\curl\class\you\use')
->disableOriginalConstructor()
->setMethods(['post'])
->getMock();

$curlMock
->expects($this->once()) // twice, exact,  etc ...
->method('post')
->with(
$this->equalTo(['project_id' => 'expected_project_id', 'task_token' => 'expected_token' ]),
$this->equalTo('http://url/endpoint')
);
//again, assuming it is public
$cut->curl = $curlMock;

// then actually execute the method you are testing:
$cut-> downloadProjectFolder('expected_project_id', 'expected_token');

Вы можете прочитать больше о том, как проверить Guzzle в официальные документы.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector