在 laravel 5.4 中测试文件上传时出错

Posted

技术标签:

【中文标题】在 laravel 5.4 中测试文件上传时出错【英文标题】:Error while testing file uploads in laravel 5.4 【发布时间】:2017-09-03 17:25:09 【问题描述】:

我正在尝试在我的应用中添加个人资料图片功能。我正在使用 TDD 方法来执行此操作。上传头像测试显示绿色。但是当我运行测试以更新个人资料图片时,它会出错。下面是代码:

控制器:

public function store(StoreAvatarRequest $request)

    $path = $request->file('avatar')->store('avatars');

    BasicInformation::updateOrCreate([
        'user_id' => auth()->id(),
    ], [
        'user_id' => auth()->id(),
        'avatar' => $path,
    ]);

    $this->showAlerts('alert-success', 'Profile Image uploaded successfully');

    return redirect()->route('avatar.index');



public function update(StoreAvatarRequest $request, $id)

    $basicProfile = BasicInformation::find($id)->first();
    $oldAvatarPath = $basicProfile->avatar;

    if ($basicProfile->user_id == auth()->id()) 
        $path = $request->file('avatar')->store('avatars');

        $basicProfile->avatar = $path;
        $basicProfile->update();

        Storage::delete($oldAvatarPath);
        $this->showAlerts('alert-success', 'Profile Image Updated Successfully');

        return redirect()->route('avatar.index');
     else 
        // TODO :: Need to add logic here
    

测试用例:

public function can_update_profile_picture()

    $this->actingAs($this->lawyer)->post(route('avatar.store'), [
        'avatar' => UploadedFile::fake()->image('avatar.jpg', 600, 600)
    ]);

    $oldImagePath = $this->lawyer->information->avatar;

    $this->actingAs($this->lawyer)->put(route('avatar.update', ['id' => $this->lawyer->information->id]), [
        'avatar' => UploadedFile::fake()->image('avatar1.jpg', 600, 600)
    ])
        ->assertRedirect(route('avatar.index'))
        ->assertSessionHas('status', 'Profile Image Updated Successfully');

    Storage::disk('local')->assertExists($this->lawyer->information->avatar);
    Storage::disk('local')->assertMissing($oldImagePath);

我在运行测试时收到以下错误:

phpUnit 5.7.19 by Sebastian Bergmann and contributors.

F                                                                   1 / 
1 (100%)

Time: 298 ms, Memory: 20.00MB

There was 1 failure:
1) Tests\Feature\Dashboard\Lawyer\Account\ProfileImageTest::can_update_profile_picture
Unable to find a file at path [local/c5tjUUQDzU4iKHauJK68Z801I5iaYJ7e3cVQ5iA1.jpeg].
Failed asserting that false is true.

【问题讨论】:

我认为你的旧头像应该是$oldImagePath = $this->lawyer->avatar 而不是$this->lawyer->information->avatar @AmrAly 那是调试错字。我已经纠正了。但我得到了同样的错误。同样对于两个断言(assertMissing 和 assertExists),我都收到了错误消息。 "无法在路径中找到文件", 也是在BasicInformation Model中定义的头像列和与User Model的hasOne关系。所以我使用 $this->lawyer->information->avatar 来引用 $oldImagePath 您是否尝试过使用文件名,例如 assertExists('avatar1.jpg');assertMissing('avatar.jpg'); 【参考方案1】:

这是一个配置问题,然后是使用 store() 或 storeAs() 方法的偏好。

首先,您必须配置 filesystems.php 以将您的测试存储磁盘识别为 fake() 磁盘:

'testing' => [
        'driver' => 'local',
        'root' => storage_path('framework/testing/disks/'),
        'visibility' => 'public',

使用该设置,您可以使用phpunit.xml 中的APP_ENV 值来默认此磁盘用于您的测试。

另外,我在我的控制器中使用storeAs(),这样我就可以在我的测试中针对我存储在assertExists() 方法中的文件名进行测试。

$request->file('avatar')->storeAs('avatar', $request->file('avatar')->getClientOriginalName())

Storage::disk('avatar')->assertExists('avatar.jpg');

这对我有用,并且在运行每个测试之前删除文件并且清理不是问题。您还可以对 hashName 进行测试,并使用 store() 方法获取响应并使用 baseName() 获取新文件的名称。

【讨论】:

我能够使用类似的方法解决这个问题。首先,我使用以下代码行初始化假存储磁盘Storage::fake('public'); 然后我使用以下代码行在发布请求中发送假文件。 $fakeImage = UploadedFile::fake()->image('avatar.jpg', 600, 600), 然后我使用以下代码行断言文件是否存在。 Storage::disk('public')->assertExists($fakeImage); @PawanKumar - 你的控制器在哪里写文件?如果您的控制器将其写入disk('public'),那么这对您有用,但不是因为您认为它有效。【参考方案2】:

我已经添加到phpunit.xml下一行:

<env name="FILESYSTEM_DRIVER" value="uploads"/>

同时检查

$image = $response->original['logo'];  // as the image name get changed in Controller
Storage::disk('uploads')->assertExists("public/uploads/$image");

其他代码与Laravel Doc类似。 您可以在Laracast 上查看讨论。

【讨论】:

以上是关于在 laravel 5.4 中测试文件上传时出错的主要内容,如果未能解决你的问题,请参考以下文章

Error Laravel 5.4以.bin格式上传.docs

在laravel 5.4(存储文件夹)中更改默认的“符号链接”文件夹

在 Laravel 5.4 上安装 cartalyst/tags 时出错

Laravel 5.4 显示上传的图片问题

在 Laravel 5.4 中获取上传失败文件的文件名

更新到 Laravel 5.4 时出错