iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 25
1
Software Development

如何一步步實踐TDD (測試驅動開發)系列 第 25

TDD 實戰 D11:Laravel 修改貼文顯示

我們目前都還沒修改過,貼文顯示的方式,今天來處理這個部分。

之前為了方便,都是直接把整個 Post 物件的內容輸出,但實際上有許多不需要的資料,同時也不容易讀,我們來把它改成一則貼文一格。

  • 關於 如何使用範例程式碼,請參考 TDD 實戰 D1
    • 本篇版本包含:5e

首頁 到 /post 的連結

紅燈 testPostLinksInIndex

// tests/Browser/IndexTest.php

class IndexTest extends DuskTestCase
{
    public function testPostLinksInIndex()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->clickLink('Post')
                    ->assertPathIs('/post');
        });
    }
}

綠燈

<!-- /reousrce/views/welcome.blade.php -->
<a href="{{ url('/post') }}">Post</a>

Post Link on Index page

重構

另外原本 Laravel 首頁預設的其他連結,也一起刪掉。

以及 tests/Feature/IndexTest.php 這個其實算是 UI 測試的範圍,因此也刪掉,只留 Dusk 的就可以了。

顯示貼文的頁面

紅燈 testPostPage

// tests/Browser/PostTest.php

class PostTest extends DuskTestCase
{
    use DatabaseMigrations;
    
    public function testPostPage()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/post')
                    ->assertSee('Post:');
        });
    }
}

綠燈

原本是直接將 Post 物件們當作字串回應,改成用一個獨立的 post 樣板。

// app/Http/Controllers/PostContrller.php
class PostController extends Controller
{
    ...
    
    public function allPost()
    {
        return view('post');
    }
}
<!-- /reousrce/views/post.blade.php -->
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <h1 class="display-4">Post:</h1>

            <div class="card">
                <div class="card-header"></div>
                <div class="card-body">
                </div>
            </div>
            
        </div>
    </div>
</div>
@endsection

顯示每則貼文

紅燈 testPostPage

// tests/Browser/PostTest.php

public function testPostPage()
    {
        $this->browse(function (Browser $browser) {
            $posts = factory(Post::class, 2)->create();
            
            $browser->visit('/post')
                    ->assertSee('Post:')
                    ->assertSee($posts[1]->post_text);
        });
    }

這裡用到了 Post 的 假資料 Factory,來修改一下。

// database/factories/PostFactory.php

use Faker\Generator as Faker;
use App\Post;
use App\User;

$factory->define(Post::class, function (Faker $faker) {
    return [
        'post_text' => $faker->text,
        'user_id' => factory(User::class)->create()->id
    ];
});

一個假的 Post 被創造時,會同時新增一筆 User,並使用它作為 user_id。

綠燈

// app/Http/Controllers/PostContrller.php
class PostController extends Controller
{
    ...
    
    public function allPost()
    {
        return view('post')
                ->with('posts', Post::all());
    }
}

->with('posts', Post::all()); 會將參數傳到 view() 使用的樣板中,而在樣板顯示時,我們將貼文內容 $posts 一則一則分開。

<!-- /reousrce/views/post.blade.php -->
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <h1 class="display-4">Post:</h1>

            @foreach ($posts as $post)
                <div class="card">
                    <div class="card-header">User: {{ $post->user_id }}</div>

                    <div class="card-body">
                        {{ $post->post_text }}
                    </div>
                </div>
            @endforeach
            
        </div>
    </div>
</div>
@endsection

Posts

重構

Dusk 的測試完成了,但再次發生類似的狀況:PHPUnit 那邊的測試沒有通過,都是在 tests/Feature/PostTest.php

其中兩個 testAllPosttestInsertPost,思考之後發現其實沒有必要。

兩個都是直接用 factory 在資料庫中新增資料,再去確認資料庫中是否有這筆資料,我們應該要測試的是我們所寫程式的邏輯,而非驗證 Laravel 提供的函式,因此這兩個測試就直接刪掉了。

還有一個錯誤發生在 testInsertPostByPostRoute,發現 ' 似乎會被轉譯成 ',暫時就只修改一下測試字串。

( $ git checkout 5e )

完成!

貼文顯示的頁面也完成了,離我們的留言板又更近了一步。


上一篇
TDD 實戰 D10:Laravel (Regression Test)
下一篇
TDD 實戰 D12:Laravel 貼文與評論
系列文
如何一步步實踐TDD (測試驅動開發)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言