在 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(存储文件夹)中更改默认的“符号链接”文件夹