63. 测试头像上传(一)

未匹配的标注

本节说明

  • 对应视频教程第 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()方法就能确保测试通过:
file
接下来我们新增测试:上传的头像必须是有效的。

    .
    .
    /** @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']
        ]);
    }
}

运行测试:
file
接下来我们新增第 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();
    }
}

运行测试:
file
运行全部测试:
file

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 查看所有版本


暂无话题~