首页 > 解决方案 > 我的存储假货没有将图像存储在测试目录中

问题描述

我正在为我的Item模型编写测试,它有要上传的图像,我希望它应该存储在测试目录中,以便在每次运行测试时清除。但事实并非如此。相反,它会创建一个item-images在两者中都命名的新目录storagetesting/disks但它使用实际storage/item-images目录而不是storage/disks/item-images.

Storage::fake('item-images')已经在测试用例之上定义了,我对此有点困惑,请帮忙。

在此处输入图像描述

tests/Feature/ItemTest.php

public function test_user_can_store_new_item()
{
    Storage::fake('item-images');
    Sanctum::actingAs(User::factory()->create());

    $images = [
        UploadedFile::fake()->image('image1.png'),
        UploadedFile::fake()->image('image2.png'),
        UploadedFile::fake()->image('image3.png'),
    ];

    $item = Item::factory()->make(['images' => $images]);

    $this->postJson(route('items.store'), $item->toArray())
        ->dump()
        ->assertCreated()
        ->assertJsonFragment($item->toArray());

    foreach ($images as $image) {
        Storage::disk('item-images')->assertExists($image->hashName());
        Storage::disk('item-images')->assertMissing('missing.png');
    }
}

app/Models/Item.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Item extends Model
{
    use HasFactory;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'category_id',
        'name',
        'description',
        'history',
    ];

    protected $with = ['category'];

    /**
     * Get the category that owns the Item
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }
}

app/Http/Controllers/ItemController.php

/**
 * Store a newly created resource in storage.
 *
 * @param  \App\Http\Requests\RequestItem  $request
 * @return \Illuminate\Http\Response
 */
public function store(RequestItem $request)
{
    $data = $request->validated();

    $item = Item::create(Arr::except($data, 'images'));

    if ($request->has('images')) {
        foreach ($request->file('images') as $image) {
            $path = $image->store('item-images');
            Image::create(['item_id' => $item->id, 'url' => $path]);
        }
    }

    return response()->json($item, 201);
}

app/Http/Requests/RequestItem.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class RequestItem extends FormRequest
{
    /**
     * 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_id' => [
                'required',
                'integer',
            ],
            'name' => [
                'required',
                'string',
                'max:255',
                Rule::unique('items', 'name'),
            ],
            'description' => [
                'required',
                'string',
                'max:255',
            ],
            'history' => [
                'string',
                'max:2500',
            ],
            'images' => [
                'required',
                'array',
                'min:1',
                'max:10',
            ],
        ];
    }
}

标签: phplaraveltesting

解决方案


我相信令人困惑的是您正在创建一个假文件,但实际上正确保存了它。$image->store('item-images');没有指定您保存它的商店,但“item-images”是路径,它将保存到默认存储。所以要么Storage::fake()是默认存储选项。

// assuming default storage is local
Storage::fake('local');

或者更改您的逻辑以指定正确的伪造存储磁盘。

Storage::disk('item-images')->putFile('path/yourfile', $image);

推荐阅读