2015-10-22 4 views
13

Я пытаюсь запустить этот функциональный тест на моем контроллере laravel. Я бы хотел протестировать обработку изображений, но для этого хочу подделать загрузку изображений. Как мне это сделать? Я нашел несколько примеров в Интернете, но никто не работает для меня. Вот что у меня есть:Как проверить загрузку файлов с помощью laravel и phpunit?

public function testResizeMethod() 
{ 
    $this->prepareCleanDB(); 

    $this->_createAccessableCompany(); 

    $local_file = __DIR__ . '/test-files/large-avatar.jpg'; 

    $uploadedFile = new Symfony\Component\HttpFoundation\File\UploadedFile(
     $local_file, 
     'large-avatar.jpg', 
     'image/jpeg', 
     null, 
     null, 
     true 
    ); 


    $values = array(
     'company_id' => $this->company->id 
    ); 

    $response = $this->action(
     'POST', 
     '[email protected]', 
     $values, 
     ['file' => $uploadedFile] 
    ); 

    $readable_response = $this->getReadableResponseObject($response); 
} 

Но контроллер не получает прошел эту проверку:

elseif (!Input::hasFile('file')) 
{ 
    return Response::error('No file uploaded'); 
} 

Так или иначе файл не передается правильно. Как мне это сделать?


Update

на основе suggestin max.lanin, я также пытался:

public function setUp() 
{ 
    // Tried with parent::setUp() here and at the end 
    // parent::setUp(); 
    $local_file = __DIR__ . '/test-files/large-avatar.jpg'; 

    print($local_file); 

    $_FILES = array(
     'file' => array (
      'tmp_name' => $local_file, 
      'name' => 'large-avatar.jpg', 
      'type' => 'image/jpeg', 
      'size' => 335057, 
      'error' => 0, 
     ), 
     'image' => array (
      'tmp_name' => $local_file, 
      'name' => 'large-avatar.jpg', 
      'type' => 'image/jpeg', 
      'size' => 335057, 
      'error' => 0, 
     ), 
    ); 

    parent::setUp(); 
} 

но без Succes. Используемый файл существует, и размер правильный.

+0

Я вижу, ты положил это в режим тестирования. Является ли загруженный файл больше максимального размера файла, установленного в php.ini? –

+0

Нет, это не так, ограничение загрузки - 2 МБ, тестовый файл - 300 КБ. –

ответ

9

Docs for CrawlerTrait.html#method_action гласит:

Параметры
Строка $ метод
строка $ действие
массив $ подстановочные
массив $ параметров
массив $ печенье
массив $ файлы
массив $ сервер
строка $ content

Так что я предполагаю, что правильный вызов должен быть

$response = $this->action(
    'POST', 
    '[email protected]', 
    [], 
    $values, 
    [], 
    ['file' => $uploadedFile] 
); 

, если оно не требует непустых символов и печенья.

В качестве примечания стороны, это ни в коем случае не единица тест.

+0

Попытка вашего предложения. Тест-жаргон кажется таким расплывчатым для меня: p Какой тип теста это будет? –

+1

@ JasperKennis, это не жаргон, а терминология, которая помогает людям оставаться на одной странице, обсуждая что-то. Неправильное использование терминологии сбивает с толку и делает обратное. То, что вы делаете, является функциональным или интеграционным тестом, в зависимости от намерений. Как правило большого пальца, единичный тест проверяет императивную часть, то есть логику одного класса, высмеивает все (разумно). Интеграционные тесты проверяют декларативную часть, то есть конфиги, шаблоны и т. д. Функциональные тесты проверяют функциональность приложения, как определено в спецификации. –

+0

Это сработало ^^ Тест все еще терпит неудачу, но он выходит за пределы указанной точки, где я застрял. Заметьте, я использую Laravel 4.2, и это не возьмите аргумент '$ wildcards'. –

4

С помощью phpunit вы можете прикрепить файл к форме с помощью метода attach().

Пример из lumen docs:

public function testPhotoCanBeUploaded() 
{ 
    $this->visit('/upload') 
     ->name('File Name', 'name') 
     ->attach($absolutePathToFile, 'photo') 
     ->press('Upload') 
     ->see('Upload Successful!'); 
} 
+2

Это не помогает, я тестирую ответы контроллера, используя метод 'action'. Это пример более высокого уровня. –

0

Добавить аналогичный setUp() метод в ваш TestCase:

protected function setUp() 
{ 
    parent::setUp(); 

    $_FILES = array(
     'image' => array(
      'name'  => 'test.jpg', 
      'tmp_name' => __DIR__ . '/_files/phpunit-test.jpg', 
      'type'  => 'image/jpeg', 
      'size'  => 499, 
      'error'  => 0 
     ) 
    ); 
} 

Это спуфинг $ _FILES глобальным и пусть Laravel думает, что есть что-то загружено.

+0

Я попробовал это, назвав файл 'image' или' file', но проверка по-прежнему не удалась. Должно ли это работать с методом '-> action' тестового модуля? –

+0

Вы поместили реальный размер и путь файла к массиву? Также попробуйте переключить строки, чтобы родительский :: setUp был после того, как вы обманули свой массив $ _FILES. –

+0

Я обновил свой вопрос, чтобы отразить это тоже, но нет, это не помогло :(Имя файла и размер верны. –

3

Для тех, кто еще спотыкаясь на этот вопрос, вы можете сделать это в наше время:

$response = $this->postJson('/product-import', [ 
     'file' => new \Illuminate\Http\UploadedFile(resource_path('test-files/large-avatar.jpg'), 'large-avatar.jpg', null, null, null, true), 
    ]); 
+0

Для вклада я добавляю конструктор '__construct ($ path, $ originalName, $ mimeType = null, $ size = null, $ error = null, $ test = false)', который вызывается из кода выше. Он отлично работает с изображениями и PDF-документами в моих модульных тестах. – barfoos

0

Вот полный пример, как проверить с помощью пользовательских файлов. Мне это нужно для разбора CSV-файлов с известным форматом, поэтому мои файлы должны были иметь точное форматирование и содержимое. Если вам нужны только изображения или файлы произвольного размера, используйте методы $ file-> fake-> image() или create(). Они приходят в комплекте с Laravel.

namespace Tests\Feature; 

use Tests\TestCase; 
use Illuminate\Http\UploadedFile; 
use Illuminate\Support\Facades\Storage; 

class PanelistImportTest extends TestCase 
{ 
    /** @test */ 
    public function user_should_be_able_to_upload_csv_file() 
    { 
     // If your route requires authenticated user 
     $user = Factory('App\User')->create(); 
     $this->actingAs($user); 

     // Fake any disk here 
     Storage::fake('local'); 

     $filePath='/tmp/randomstring.csv'; 

     // Create file 
     file_put_contents($filePath, "HeaderA,HeaderB,HeaderC\n"); 

     $this->postJson('/upload', [ 
      'file' => new UploadedFile($filePath,'test.csv', null, null, null, true), 
     ])->assertStatus(200); 

     Storage::disk('local')->assertExists('test.csv'); 
    } 
} 

Вот контроллер идти с ним:

namespace App\Http\Controllers; 

use Illuminate\Http\Request; 
use App\Http\Controllers\Controller; 
use Illuminate\Support\Facades\Storage; 

class UploadController extends Controller 
{ 
    public function save(Request $request) 
    { 
     $file = $request->file('file'); 

     Storage::disk('local')->putFileAs('', $file, $file->getClientOriginalName()); 

     return response([ 
      'message' => 'uploaded' 
     ], 200); 
    } 
} 
Смежные вопросы