编写 然后编写注册测试用例:编写 最后,编写退出测试用例:编辑 编写 要运行测试的话的随时运行
LoginTest 代码如下:1
class LoginTest extends TestCase2
{3
public function testRequiresEmailAndLogin()4
{5
$this->json('POST', 'api/login')6
->assertStatus(422)7
->assertJson([8
'email' => ['The email field is required.'],9
'password' => ['The password field is required.'],10
]);11
}12
13
public function testUserLoginsSuccessfully()14
{15
$user = factory(User::class)->create([16
'email' => 'test@laravelacademy.org',17
'password' => bcrypt('test123'),18
]);19
20
$payload = ['email' => 'test@laravelacademy.org', 'password' => 'test123'];21
22
$this->json('POST', 'api/login', $payload)23
->assertStatus(200)24
->assertJsonStructure([25
'data' => [26
'id',27
'name',28
'email',29
'created_at',30
'updated_at',31
'api_token',32
],33
]);34
35
}36
}1
php artisan make:test RegisterTestRegisterTest 代码如下:1
class RegisterTest extends TestCase2
{3
public function testsRegistersSuccessfully()4
{5
$payload = [6
'name' => 'John',7
'email' => 'john@toptal.com',8
'password' => 'toptal123',9
'password_confirmation' => 'toptal123',10
];11
12
$this->json('post', '/api/register', $payload)13
->assertStatus(201)14
->assertJsonStructure([15
'data' => [16
'id',17
'name',18
'email',19
'created_at',20
'updated_at',21
'api_token',22
],23
]);;24
}25
26
public function testsRequiresPasswordEmailAndName()27
{28
$this->json('post', '/api/register')29
->assertStatus(422)30
->assertJson([31
'name' => ['The name field is required.'],32
'email' => ['The email field is required.'],33
'password' => ['The password field is required.'],34
]);35
}36
37
public function testsRequirePasswordConfirmation()38
{39
$payload = [40
'name' => 'John',41
'email' => 'john@toptal.com',42
'password' => 'toptal123',43
];44
45
$this->json('post', '/api/register', $payload)46
->assertStatus(422)47
->assertJson([48
'password' => ['The password confirmation does not match.'],49
]);50
}51
}1
php artisan make:test LogoutTestLogoutTest 代码如下:1
class LogoutTest extends TestCase2
{3
public function testUserIsLoggedOutProperly()4
{5
$user = factory(User::class)->create(['email' => 'user@test.com']);6
$token = $user->generateToken();7
$headers = ['Authorization' => "Bearer $token"];8
9
$this->json('get', '/api/articles', [], $headers)->assertStatus(200);10
$this->json('post', '/api/logout', [], $headers)->assertStatus(200);11
12
$user = User::find($user->id);13
14
$this->assertEquals(null, $user->api_token);15
}16
17
public function testUserWithNullToken()18
{19
// Simulating login20
$user = factory(User::class)->create(['email' => 'user@test.com']);21
$token = $user->generateToken();22
$headers = ['Authorization' => "Bearer $token"];23
24
// Simulating logout25
$user->api_token = null;26
$user->save();27
28
$this->json('get', '/api/articles', [], $headers)->assertStatus(401);29
}30
}注:在测试期间,Laravel 应用并不会在发起新请求时再次初始化,所以会在请求之间保存当前用户到 TokenGuard 实例,也因此我们不得不将退出测试一分为二,以避免受之前缓存用户的影响。测试文章 API 接口的代码也很简单:1
php artisan make:test ArticleTestArticleTest 代码如下:1
class ArticleTest extends TestCase2
{3
public function testsArticlesAreCreatedCorrectly()4
{5
$user = factory(User::class)->create();6
$token = $user->generateToken();7
$headers = ['Authorization' => "Bearer $token"];8
$payload = [9
'title' => 'Lorem',10
'body' => 'Ipsum',11
];12
13
$this->json('POST', '/api/articles', $payload, $headers)14
->assertStatus(200)15
->assertJson(['id' => 1, 'title' => 'Lorem', 'body' => 'Ipsum']);16
}17
18
public function testsArticlesAreUpdatedCorrectly()19
{20
$user = factory(User::class)->create();21
$token = $user->generateToken();22
$headers = ['Authorization' => "Bearer $token"];23
$article = factory(Article::class)->create([24
'title' => 'First Article',25
'body' => 'First Body',26
]);27
28
$payload = [29
'title' => 'Lorem',30
'body' => 'Ipsum',31
];32
33
$response = $this->json('PUT', '/api/articles/' . $article->id, $payload, $headers)34
->assertStatus(200)35
->assertJson([36
'id' => 1,37
'title' => 'Lorem',38
'body' => 'Ipsum'39
]);40
}41
42
public function testsArtilcesAreDeletedCorrectly()43
{44
$user = factory(User::class)->create();45
$token = $user->generateToken();46
$headers = ['Authorization' => "Bearer $token"];47
$article = factory(Article::class)->create([48
'title' => 'First Article',49
'body' => 'First Body',50
]);51
52
$this->json('DELETE', '/api/articles/' . $article->id, [], $headers)53
->assertStatus(204);54
}55
56
public function testArticlesAreListedCorrectly()57
{58
factory(Article::class)->create([59
'title' => 'First Article',60
'body' => 'First Body'61
]);62
63
factory(Article::class)->create([64
'title' => 'Second Article',65
'body' => 'Second Body'66
]);67
68
$user = factory(User::class)->create();69
$token = $user->generateToken();70
$headers = ['Authorization' => "Bearer $token"];71
72
$response = $this->json('GET', '/api/articles', [], $headers)73
->assertStatus(200)74
->assertJson([75
[ 'title' => 'First Article', 'body' => 'First Body' ],76
[ 'title' => 'Second Article', 'body' => 'Second Body' ]77
])78
->assertJsonStructure([79
'*' => ['id', 'body', 'title', 'created_at', 'updated_at'],80
]);81
}82
}composer test 即可。 至此,我们已经完成了 API 接口的编写和测试,下一篇我们会基于 JWT 对 API 进行认证同时整合进 Vue SPA 做一个更偏向实战的教程,敬请期待。













87 条评论
为啥不用 PHPStorm 呢,会自动给你引进来
学院君我想问下我测试注册接口的时候返回的{ "message": "Type error: Argument 1 passed to App\Http\Controllers\Auth\RegisterController::registered() must be an instance of App\Http\Controllers\Auth\Request, instance of Illuminate\Http\Request given, called in D:\phpstudy\PHPTutorial\WWW\laravel\vendor\laravel\framework\src\Illuminate\Foundation\Auth\RegistersUsers.php on line 37", "exception": "Symfony\Component\Debug\Exception\FatalThrowableError", "file": ...这个错误,但是我数据库却写进去了是什么情况
@ 学院君 注册时users表生成的api_token值 和登录时返回的api_token值不一样是什么情况?
登陆操作以后 我换个控制器 获取用户信息 为什么获取不到
加了认证中间件以后 登陆之后 访问/articles 还是 { "message": "Unauthenticated." }
API 认证后获取到的 token 后续每次请求都要在请求参数中带上 这里采用 Authorization 请求头的方式传递 不同于传统的通过 Cookie+Session 实现的认证 这种情况下 SessionID 写入到 Cookie 中每次自动带上
Laravel6.0 没有
str_random()函数了,取而代之的是Str::random()方法