63. 测试头像上传(一)
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频教程第 63 小节:Testing Avatar Uploads
本节内容
本节我们开始开发头像上传的功能。按照惯例,我们先新建测试:
forum\tests\Feature\AddAvatarTest.php
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class AddAvatarTest extends TestCase
{
use DatabaseMigrations;
/** @test */
public function only_members_can_add_avatars()
{
$this->withExceptionHandling();
$this->json('POST','api/users/1/avatar')
->assertStatus(401);
}
}
添加路由:
forum\routes\web.php
.
.
Route::get('api/users','Api\UsersController@index');
Route::post('api/users/{user}/avatar','Api\UserAvatarController@store')->middleware('auth')->name('avatar');
然后新建控制器:
php artisan make:controller "Api\UserAvatarController"
由于我们启用了Auth
中间件,我们甚至不用建立store()
方法就能确保测试通过:
接下来我们新增测试:上传的头像必须是有效的。
.
.
/** @test */
public function a_valid_avatar_must_be_provided()
{
$this->withExceptionHandling()->signIn();
$this->json('POST','api/users/' . auth()->id() . '/avatar',[
'avatar' => 'not-an-image'
])->assertStatus(422);
}
}
现在我们需要新增store()
方法了:
forum\app\Http\Controllers\Api\UserAvatarController.php
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserAvatarController extends Controller
{
public function store()
{
$this->validate(request(),[
'avatar' => ['required','image']
]);
}
}
运行测试:
接下来我们新增第 3 个测试,用来测试文件上传。Illuminate\Http\UploadedFile
类提供了一个fake
方法,可用其生成用于测试的模拟文件或图像。将其与 Storage facade 的fake
方法结合使用,可极大地简化文件上传的测试。
详细文档见 测试文件上传 和 Storage 模拟
.
.
/** @test */
public function a_user_may_add_an_avatar_to_their_profile()
{
$this->signIn();
Storage::fake('public');
$this->json('POST','api/users/' . auth()->id() . '/avatar',[
'avatar' => $file = UploadedFile::fake()->image('avatar.jpg')
]);
$this->assertEquals('avatars/' . $file->hashName(),auth()->user()->avatar_path);
Storage::disk('public')->assertExists('avatars/' . $file->hashName());
}
}
修改迁移文件,增加avatar_path
字段:
forum\database\migrations\2014_10_12_000000_create_users_table.php
.
.
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->string('avatar_path')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
.
.
别忘了修改模型文件,使其可更新:
forum\app\User.php
.
.
protected $fillable = [
'name', 'email', 'password','avatar_path'
];
.
.
然后在控制器中增加相应逻辑:
forum\app\Http\Controllers\Api\UserAvatarController.php
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserAvatarController extends Controller
{
public function store()
{
$this->validate(request(),[
'avatar' => ['required','image']
]);
auth()->user()->update([
'avatar_path' => request()->file('avatar')->store('avatars','public')
]);
return back();
}
}
运行测试:
运行全部测试:
推荐文章: