Ray Lee | 李宗叡
Learn or Die
Published in
32 min readDec 26, 2020

--

Photo by Scott Graham on Unsplash

# 版本

Laravel 8.x

# 前言

我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。

# 目錄

Laravel — 官方文件原子化翻譯 — 目錄

# Introduction

以下的 Laravel example code 的意思是?

  • Example:
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
public function testBasicTest()
{
$response = $this->get('/');

$response->assertStatus(200);
}
}
  • Answer: 如果對 ‘/’ 發 request, response 將會是 200, 如果不是則測試不通過

# Customizing Request Headers

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->withHeaders([
'X-Header' => 'Value',
])->json('POST', '/user', ['name' => 'Sally']);

$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
  • Answer: 自訂 request 的 header, 然後以 POST 的方式帶著參數發到 ‘/user’ url 並斷言需以 JSON 格式回傳 ‘created’ => true, status code 為 201

Laravel Testing 中, CSRF token 會運作嗎?

不會

# Cookies

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testCookies()
{
$response = $this->withCookie('color', 'blue')->get('/');

$response = $this->withCookies([
'color' => 'blue',
'name' => 'Taylor',
])->get('/');
}
}
  • Answer: 建立一個 test case, 定義 cookie 為 ‘color’ => ‘blue’, 並向 ‘/’ 發 GET request, 上面兩種定義 cookie 的方式皆可

# Debugging Responses

以下的 Laravel example code 的意思是?

  • Example:
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
public function testBasicTest()
{
$response = $this->get('/');

$response->dumpHeaders();

$response->dumpSession();

$response->dump();
}
}
  • Answer: 對 ‘/’ 發 GET request, 並印出 headers, session, 以及整個 response 方便 debug

# Session / Authentication

以下的 Laravel Testing example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testApplication()
{
$response = $this->withSession(['foo' => 'bar'])
->get('/');
}
}
  • Answer: 定義 session 載入檔案 [‘foo’ => ‘bar’], 並發送 ‘/’ GET request

以下的 Laravel example code 的意思是?

  • Example:
<?php
use App\Models\User;

class ExampleTest extends TestCase
{
public function testApplication()
{
$user = User::factory()->create();

$response = $this->actingAs($user, 'api')
->withSession(['foo' => 'bar'])
->get('/');
}
}
  • Answer: 建立一個 user, 並指定由這個 user 登入, 使用 ‘api’ guard 來驗證身份 (也可不設), 並帶著 session [‘foo’ => ‘bar’], 發送 ‘/’ GET request

# Testing JSON APIs

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->postJson('/user', ['name' => 'Sally']);

$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}
  • Answer: 使用 JSON 格式發送 POST request, 發送位址為 ‘/user’, body 為 [‘name’ => ‘Sally’] 並斷言回傳 status code 201, 以及 JSON “created” : “true”

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->postJson('/user', ['name' => 'Sally']);

$this->assertTrue($response['created']);
}
}
  • Answer: 使用 JSON 格式發送 POST request, 發送位址為 '/user', body 為 ['name' => 'Sally'] 並斷言回傳 的 JSON response 的 'created' value 為 true

# Verifying An Exact JSON Match

以下的 Laravel example code 的意思是?

  • Example:
<?php
class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);

$response
->assertStatus(201)
->assertExactJson([
'created' => true,
]);
}
}
  • Answer: 使用 JSON 格式發送 POST request, 發送位址為 '/user', body 為 ['name' => 'Sally'] 並斷言 response 會是 JSON ['created => true], 若不是則 test fail

# Verifying JSON Paths

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testBasicExample()
{
$response = $this->json('POST', '/user', ['name' => 'Sally']);

$response
->assertStatus(201)
->assertJsonPath('team.owner.name', 'foo');
}
}
  • Answer: 使用 JSON 格式發送 POST request, 發送位址為 '/user', body 為 ['name' => 'Sally'] 並斷言 response 需包含 status code 201, 以及在 'team.owner.name' 的路徑, value 需為 'foo'

# Testing File Uploads

以下的 Laravel example code 的意思是?

  • Example:
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ExampleTest extends TestCase
{
public function testAvatarUpload()
{
Storage::fake('avatars');

$file = UploadedFile::fake()->image('avatar.jpg');

$response = $this->json('POST', '/avatar', [
'avatar' => $file,
]);

Storage::disk('avatars')->assertExists($file->hashName());

Storage::disk('avatars')->assertMissing('missing.jpg');
}
}
  • Answer:
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ExampleTest extends TestCase
{
public function testAvatarUpload()
{
// fake 一個 storage disk 名為 'avatars'
Storage::fake('avatars');

// fake 一個 image 名為 'avatar.jpg', 並 assign 到 $file
$file = UploadedFile::fake()->image('avatar.jpg');

// 對 '/avatar' 發起一個 JSON POST Request, 帶著 ['avatar' => $file]
$response = $this->json('POST', '/avatar', [
'avatar' => $file,
]);

// 斷言在 'avatars' 這個 storage disk 中, 有 $file 的 hash name, 若無則 test fails
Storage::disk('avatars')->assertExists($file->hashName());

// 斷言在 'avatars' 這個 storage disk 中, 沒有 'missing.jpg' 這個檔案, 若有則 test fails
Storage::disk('avatars')->assertMissing('missing.jpg');
}
}

# Fake File Customization

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testBasicExample()
{
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);
}
}
  • Answer: fake 一個 image, 名為 'avatar.jpg', 定義 width, height, 以及 size

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testBasicExample()
{
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes, 'application/pdf');
}
}
  • Answer: 使用 faker 的 create method 建立一個 PDF file, 可以指定 size 以及 mimeType (optional)

# Testing Views

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testWelcomeView()
{
$view = $this->view('welcome', ['name' => 'Taylor']);

$view->assertSee('Taylor');
}
}
  • Answer: test 的 view method 會 return 一個 Illuminate\Testing\TestView instance, 可帶入 view name 以及 parameters, TestView instance 也提供了很多 assertion method: assertsee, assertSeeInOrder, assertSeeText, assertSeeTextInOrder, assertDontSee, assertDontSeeText

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testWelcomeView()
{
$contents = (string) $this->view('welcome');
}
}
  • Answer: 若有需要, 也可取得 raw, rendered view 的內容

# Sharing Errors

以下的 Laravel example code 的意思是?

  • Example:
<?php

class ExampleTest extends TestCase
{
public function testWelcomeView()
{
$view = $this->withViewErrors([
'name' => ['Please provide a valid name.']
])->view('form');

$view->assertSee('Please provide a valid name.');
}
}
  • Answer: 將模擬的 error message 'name' => ['Please provide a valid name.']待到指定的 view 'form'

# Rendering Blade & Components

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$view = $this->blade(
'<x-component :name="$name" />',
['name' => 'Taylor']
);

$view->assertSee('Taylor');
  • Answer: 使用 blade() arg1 定義使用名為 component 的 component, 且定義帶入的參數為 $name arg2 定義 $name 為 'Taylor' 最後斷言 $view 需可看到 'Taylor'

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$view = $this->component(Profile::class, ['name' => 'Taylor']);

$view->assertSee('Taylor');
  • Answer: 使用 component() arg1 使用的 component class arg2 定義帶入的 args key/value 最後斷言 $view 需可看到 'Taylor'

# Available Assertions

# Response Assertions

# assertCookie

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertCookie($cookieName, $value = null);
  • Answer: 斷言 response 帶有指定 $cookie

# assertCookieExpired

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertCookieExpired($cookieName);
  • Answer: 斷言 response 帶有指定 $cookie, 且該 cookie 已過期

# assertCookieNotExpired

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertCookieNotExpired($cookieName);
  • Answer: 斷言 response 帶有指定 $cookie, 且該 cookie 還沒過期

# assertCookieMissing

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertCookieMissing($cookieName);
  • Answer: 斷言 response 未帶有指定 cookie

# assertCreated

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertCreated();
  • Answer: 斷言 response status code 為 201

# assertDontSee

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertDontSee($value, $escaped = true);
  • Answer: 斷言 response 含有指定 $value string 預設會自動 escape string, 除非 arg2 為 false

# assertDontSeeText

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertDontSeeText($value, $escaped = true);
  • Answer: 斷言 response text 中含有指定 $value string 預設會自動 escape string, 除非 arg2 為 false 在跑此 assertion 之前, 會先把 response 的內容用 PHP function strip_tags 跑過

# assertExactJson

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertExactJson(array $data);
  • Answer: 斷言 response 中, 含有完全符合指定 $data 的 JSON data

# assertForbidden

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertForbidden();
  • Answer: 斷言 response 含有 HTTP status code 403

# assertHeader

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertHeader($headerName, $value = null);
  • Answer: 斷言 response 含有指定的 header 以及其 value

# assertHeaderMissing

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertHeaderMissing($headerName);
  • Answer: 斷言 response 不含有指定 header

# assertJson

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJson(array $data, $strict = false);
  • Answer: 斷言 response 含有指定 JSON data assertJson 會將 response 轉成 array, 並且使用 PHPUnit::assertArraySubset 確認指定的 array 存在於 JSON response, 所以如果該 JSON response 中有其他 property, test 也會 pass 過去

# assertJsonCount

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJsonCount($count, $key = null);
  • Answer: 斷言 response JSON 中, 指定的 $key 為 array, 而裡頭的 item 數量跟斷言的 $count 數量相符

# assertJsonFragment

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
Route::get('/users', function () {
return [
'users' => [
[
'name' => 'Taylor Otwell',
],
],
];
});

$response->assertJsonFragment(['name' => 'Taylor Otwell']);
  • Answer: 斷言 response 中, 在某個位置有著 ['name' => 'Taylor Otwell'

# assertJsonMissing

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJsonMissing(array $data);
  • Answer: 斷言 response 中, 並無 JSON $data 假如 Response 為 ['a' => 1, 'b' => 2], 那如果 $data 為 ['a' => 2, 'b' => 2], 這樣也算 fail

# assertJsonMissingExact

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJsonMissingExact(array $data);
  • Answer: 斷言 response 中, 並無 JSON $data 假如 Response 為 ['a' => 1, 'b' => 2], 那如果 $data 為 ['a' => 2, 'b' => 2], 因為沒有完全符合, 這樣便不算 fail, 然而測試結果為 not perform any assertion, 不確定這樣的行為是否正常, 預期行為應為 pass

# assertJsonMissingValidationErrors

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJsonMissingValidationErrors($keys);
  • Answer: 斷言 response 中, 並無指定 $key 的 JSON validation error

# assertJsonPath

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJsonPath($path, array $data, $strict = true);
  • Answer: 斷言 response 在指定的 $path 位置含有指定的 $data 見範例如下:
  • Demonstration:
<?php
// response
{
"user": {
"name": "Steve Schoger"
}
}

// test method
$response->assertJsonPath('user.name', 'Steve Schoger');

# assertJsonStructure

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJsonStructure(array $structure);
  • Answer: 斷言 response 為定義的 JSON 結構 見範例如下:
  • Demonstration:
<?php
// response
{
"user": {
"name": "Steve Schoger"
}
}

// test method
$response->assertJsonStructure([
'user' => [
'name',
]
]);

# assertJsonValidationErrors

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertJsonValidationErrors(array $data);
  • Answer: 斷言 response 需含有指定 keys 的 errors, 適用於 validator error 是以 JSON 結構回傳, 而不是置於 session 當中

# assertLocation

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertLocation($uri);
  • Answer: 斷言 response 的 Location header 的 value 為 $uri

# assertNoContent

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertNoContent($status = 204)
  • Answer: 斷言 response 需為 no content, 且 status code 為 204

# assertNotFound

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertNotFound();
  • Answer: 斷言 response status code 需為 404

# assertOk

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertOk()
  • Answer: 斷言 response status code 需為 200

# assertPlainCookie

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertPlainCookie($cookieName, $value = null);
  • Answer: 斷言 response 含有指定的 unencrypted cookie

# assertRedirect

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertRedirect($uri);
  • Answer: 斷言 response 為 redirect 到 $uri

# assertSee

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSee($value, $escaped = true);
  • Answer: 斷言 response 含有 string $value, 預設會 escape 此 string, 可指定為 false

# assertSeeInOrder

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSeeInOrder(array $values, $escaped = true);
  • Answer: 斷言 response 中, string 的順序如 $values 的定義, 預設 escape, 可變更為 false

# assertSeeText

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSeeText($value, $escaped = true);
  • Answer: 斷言 response text 中有 string $value, 預設會 escape string, 可改為 false response 內容會先經過 strip_tags 處理過, 才會到 assertion

# assertSeeTextInOrder

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSeeTextInOrder(array $values, $escaped = true);
  • Answer: 斷言 response text 中有 string $value, 並且照定義的順序排列, 預設會 escape string, 可改為 false response 內容會先經過 strip_tags 處理過, 才會到 assertion

# assertSessionHas

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionHas($key, $value = null);
  • Answer: 斷言 session $key 含有 $value

# assertSessionHasInput

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionHasInput($key, $value = null);
  • Answer: 斷言 session 在 flashed input array 含有指定的 key / value

# assertSessionHasAll

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionHasAll(array $data);
  • Answer: 斷言 session 在 含有指定的 array [key / value] 例如 session 含有 namestatus key, 可定義如下:
  • Demonstration:
<?php
$response->assertSessionHasAll([
'name' => 'Taylor Otwell',
'status' => 'active',
]);

# assertSessionHasErrors

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionHasErrors(
array $keys, $format = null, $errorBag = 'default'
);
  • Answer: 斷言 session 中含有指定的 errors, 可以只斷言 key, 也可 key / value 這個適合用來測試會將 error 放入 session 的 route, 而不是將 error 導出 JSON response 的 route 例如, 斷言 session 中有 error message filed name, email (demonstration 1) 也可指定 error message key / value (demonstration 2)
  • Demonstration1:
<?php
$response->assertSessionHasErrors(['name', 'email']);
  • Demonstration2:
<?php
$response->assertSessionHasErrors([
'name' => 'The given name was invalid.'
]);

# assertSessionHasErrorsIn

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);
  • Answer: 斷言 session 中, messageBag $errorBag 中含有指定的 error / message $keys, 可定義 key 以及 key / value

# assertSessionHasNoErrors

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionHasNoErrors();
  • Answer: 斷言 session 中沒有 validation errors

# assertSessionDoesntHaveErrors

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');
  • Answer: 斷言 session 中沒有指定的 error key

# assertSessionMissing

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSessionMissing($key);
  • Answer: 斷言 session 中沒有指定的 $key

# assertStatus

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertStatus($code);
  • Answer: 斷言 response 的 status code 為 $code

# assertSuccessful

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertSuccessful();
  • Answer: 斷言 response 的 status code 為 (>= 200 and < 300)

# assertUnauthorized

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertUnauthorized();
  • Answer: 斷言 response 的 status code 為 401

# assertViewHasAll

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertViewHasAll(array $data);
  • Answer:
<?php
// 斷言 response view 中含有指定的 keys 或是多組 key / value
$rseponse->assertViewHasAll([
'name',
'email',
]);

$rseponse->assertViewHasAll([
'name' => 'Taylor Otwell',
'email' => 'taylor@example.com,',
]);

# assertViewIs

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertViewIs($value);
  • Answer: 斷言 response view name 跟 $value 一樣

# assertViewMissing

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$response->assertViewMissing($key);
  • Answer: 斷言 response view 中沒有 $key

# Authentication Assertions

# assertAuthenticated

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$this->assertAuthenticated($guard = null);
  • Answer: 斷言 user is authenticated

# assertGuest

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$this->assertGuest($guard = null);
  • Answer: 斷言 user is not authenticated

# assertAuthenticatedAs

以下的 Laravel Test example code 的意思是?

  • Example:
<?php
$this->assertAuthenticatedAs($user, $guard = null);
  • Answer: 斷言 $user is authenticated

--

--

Ray Lee | 李宗叡
Learn or Die

It's Ray. I do both backend and frontend, but more focus on backend. I like coding, and would like to see the whole picture of a product.