部落格要能夠顯示文章,首先我們的資料庫中要先有文章。
所以今天要來加入一個路由,用來新增一則貼文。
4e
、4f
。class PostTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->withoutExceptionHandling();
}
public function testInsertPostByGetRoute()
{
$text = "It's a new post.";
$this->get("/posts/insert?post_text=$text");
$response = $this->get('/posts/');
$response->assertSee($text);
}
}
我們新增了兩個函式:setUp()
與testInsertPostByGetRoute()
。
setUp()
是所謂的 Fixture 函式 (中文直翻:"固定裝置"),用途是在每個測試函式執行前,都會先執行 setUp 的內容。
將那些同樣的事前設定移到 setUp,就能減少在各個測試中重複的程式碼,其他類似的還有 tearDown()
在每個測試後執行,另外也可以只在整個測試類別執行一次的,有 setUpBeforeClass()
跟 tearDownAfterClass()
可以幫忙。
以及在 Laravel 中使用 fixture,需要呼叫,父類別的函式:parent::setUp()
。
有時 PHPUnit 預設並不會把所有錯誤訊息列出來,這樣寫測試時會不容易追蹤錯誤的源頭。
因此在 setUp 中加入 withoutExceptionHandling。
// routes/web.php
Route::get('/posts/insert', function(Request $request) {
$post = new Post;
$post->post_text = $request->input('post_text');
$post->save();
});
( $ git checkout 4e
)
這裡的 $post
是 Eloquent 的用法,所謂 ORM (Object Relational Mapping)。
這個 Post
是存取資料庫的介面,同時也包含該筆資料的內容。
建立物件後用直接用 成員變數名稱設值,再以 save()
存進資料庫。
$request
物件會接收當次 request 的輸入,用 input('key')
取值。
這邊來做一次重構,體驗一下 TDD 的魔力。
我們原本直接把函式內容,用 closure 的方式寫在 路由中,也就是
Route::get('/posts/insert', function(Request $request) {
...
});
然而我們可以借助 MVC 的架構,將 路由
與 執行邏輯
分開,也就是 View
與 Controller
,讓程式碼能夠更簡潔易讀。
以 Artisan 指令創建 PostController:
$ php artisan make:controller PostController
將剛剛路由中的程式碼搬過來。
<?php
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class PostController extends Controller
{
public function insertPost(Request $request)
{
$post = new Post;
$post->post_text = $request->input('post_text');
$post->save();
}
public function allPost()
{
$response = "All Posts: ";
$posts = Post::all();
foreach ($posts as $post) {
$response .= $post;
}
return $response;
}
}
接著再把路由改成,呼叫這裡的控制器函式。
Route::get('/posts/', 'PostController@allPost');
Route::get('/posts/insert', 'PostController@insertPost');
( $ git checkout 4f
)
於是路由這邊各自變成了簡短的一行,接著再次執行測試。
$ ./vendor/bin/phpunit
PHPUnit 8.3.5 by Sebastian Bergmann and contributors.
.... 4 / 4 (100%)
Time: 446 ms, Memory: 26.00 MB
通過!
即使做了一些修改,但是原本的測試依然通過,瞬間就能夠確保,我們的程式並沒有被破壞掉,感覺還不賴。
今天我們完成了新增貼文的路由,接著試了重構看看,明天再來繼續強化他。