2016-01-18 3 views
0

У меня есть функция, которая выглядит как:PHPUnit - Глумление Transfer Object Класс жрать/S3 с обетованием методы

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 - что сам по себе, в основном, абстрагируются от жрать 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()?

ответ

1

Не так много вы можете сделать о 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'); 

Вы можете прочитать больше о том, чтобы проверить жрать в official docs.

Смежные вопросы