在Laravel中测试文件上传

时间:2019-08-23 12:13:06

标签: php laravel dropzone.js

我正在将Laravel 5.8与Dropzone.js结合使用,以将文件上传到库中,而我能够成功地做到这一点。我认为写一个测试来验证这一点是一种好习惯,但是它总是失败。

我在这个问题中也看到过类似的情况:Laravel dusk: test file upload with Dropzone.js

我的控制器方法看起来像只是grep -o '"filesize":\s[0-9]*' files.json ,看起来像这样:

store

/** * Store a new library file in the database * * @param StoreArticle $request * @return void */ public function store(StoreLibrary $request) { $data = $request->validated(); $category = $data['category']; $files = $data['file']; foreach ($files as $file) { $original_name = $file->getClientOriginalName(); $mime_type = $file->getClientOriginalExtension(); $size = $file->getSize(); // Generate a name for this file $system_generated_name = sha1(date('YmdHis') . str_random(30)) . '.' . $file->getClientOriginalExtension(); // Store the file on the disk 'library' $path = Storage::disk('library')->putFileAs(null, $file, $system_generated_name); // Store a reference to this file in the database Library::create([ 'display_name' => $original_name, 'file_name' => $system_generated_name, 'mime_type' => $mime_type, 'size' => $size, 'disk' => $this->disk, 'storage_location' => $path, 'category' => $category, ]); } // Return a JSON response return response()->json([ 'success' => true, 'file' => [ 'original_name' => $original_name, 'generated_name' => $system_generated_name, 'path' => $path, 'size' => $size, ] ], 200); } 类是StoreLibrary,看起来像这样:

FormRequest

我编写的测试如下:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreLibrary extends FormRequest
{
    /**
     * Set allowed extensions for each file category
     * This can be appended to as necessary as it's somewhat restrictive
     */
    private $image_ext = [
        'jpg', 'jpeg', 'png', 'gif', 'ai', 'svg', 'eps', 'ps'
    ];

    private $audio_ext = [
        'mp3', 'ogg', 'mpga'
    ];

    private $video_ext = [
        'mp4', 'mpeg'
    ];

    private $document_ext = [
        'doc', 'docx', 'dotx', 'pdf', 'odt', 'xls', 'xlsm', 'xlsx', 'ppt', 'pptx', 'vsd'
    ];

    /**
     * Merge all listed extensions into one massive array
     *
     * @return array Extensions of all file types
     */
    private function extension_whitelist()
    {
        return array_merge($this->image_ext, $this->audio_ext, $this->video_ext, $this->document_ext);
    }

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'category' => [
                'required',
                'string'
            ],
            'file.*' => 'required|file|mimes:' . implode(',', $this->extension_whitelist()) . '|max:50000'
        ];
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'category.required' => 'A category is required when uploading library files.',
            'file.*.required' => 'Please select a file to upload',
            'file.*.mimes' => 'This type of file is not permitted on the Intranet'
        ];
    }
}

运行测试总是返回以下错误/** @test */ public function a_user_with_permission_can_add_files_to_the_library() { $this->withoutExceptionHandling(); Storage::fake('library'); $this->setupPermissions(); $user = factory(User::class)->create(); $user->assignRole('admin'); // Assert the uploading an image returns a 200 response $this->actingAs($user) ->post(route('admin.library.store'), [ 'category' => 'Some category', 'file' => UploadedFile::fake()->create("test.jpg", 100) ])->assertStatus(200); Storage::disk('library')->assertExists("test.jpg"); } ,但是文件输入肯定称为文件。

关联的刀片文件部分:

ErrorException: Undefined index: file

Vue代码:

<form autocomplete="off">                

                        <div class="form-group">
                            <label for="category">What category do these files fall into? <span class="required">*</span></label>
                            <select v-model="category" name="category" id="category" class="form-control form-control--citibase">
                                <option value="">Select a category</option>
                                @foreach($categories as $category)
                                <option value="{{ $category }}">{{ $category }}</option>
                                @endforeach
                            </select>
                        </div>

                        <div class="form-group">
                            <vue-dropzone 
                                ref="myVueDropzone" 
                                id="dropzone" 
                                v-bind:options="dropzoneOptions" 
                                v-bind:duplicate-check=true
                                v-on:vdropzone-sending="sendFile"
                                v-on:vdropzone-success-multiple="uploadSuccessful"
                                v-on:vdropzone-queue-complete="queueComplete"
                                v-on:vdropzone-error="uploadError">
                            </vue-dropzone>
                        </div>


                        <div class="d-flex justify-content-end">
                            <input type="button" v-on:click="upload_files" class="btn btn-pink" value="Upload files"/>
                        </div>
                    </form>

1 个答案:

答案 0 :(得分:0)

我设法找到了解决此问题的方法。这是因为openjdk是一个数组,这意味着在测试时需要具有键和索引。

这在下面的代码中显示:

file