Подтвердить что ты не робот

Как проверить загрузку файлов с помощью laravel и phpunit?

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

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');
}

Итак, как-то файл не передан правильно. Как мне это сделать?


Обновление

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

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();
}

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

4b9b3361

Ответ 1

Документы для CrawlerTrait.html # method_action читают:

Параметры
string $method
string $action
массив $подстановочных знаков
Параметры массива $массив $cookies
array $files
массив $server
string $content

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

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

если для этого не требуются непустые подстановочные знаки и файлы cookie.

В качестве побочного примечания это ни в коем случае не тест unit.

Ответ 2

Если кто-то еще споткнется на этот вопрос, вы можете сделать следующее:

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

Ответ 3

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

Пример из документов lumen:

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

Ответ 4

Вот полный пример того, как тестироваться с помощью настраиваемых файлов. Мне это нужно для разбора 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);
    }
}

Ответ 5

Сначала импортируйте необходимые вещи

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

Затем создайте поддельный файл для загрузки.

Storage::fake('local');
$file = UploadedFile::fake()->create('file.pdf');

Затем создайте данные JSON для передачи файла. Пример

$parameters =[
            'institute'=>'Allen Peter Institute',
            'total_marks'=>'100',
            'aggregate_marks'=>'78',
            'percentage'=>'78',
            'year'=>'2002',
            'qualification_document'=>$file,
        ];

Затем отправьте данные в свой API.

$user = User::where('email','[email protected]')->first();

$response = $this->json('post', 'api/user', $parameters, $this->headers($user));

$response->assertStatus(200);

Я надеюсь, что это сработает.

Ответ 6

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

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 думает, что есть что-то загруженное.