Repository

用 Repository 包裝 Model

  • 不讓 Controller 直接接觸 Model
  • 避免 Controller 肥大
  • 封裝資料存取邏輯
  • 抽換資料庫實作較容易

建立 app/Repositories/ArticleRepository.php

namespace App\Repositories;

use App\Article;

class ArticleRepository
{
}

這就是我們要測試的目標。

再建立 tests/ArticleRepositoryTest.php 測試類別:

use App\Repositories\ArticleRepository;

// 一樣要先繼承
class ArticleRepositoryTest extends TestCase
{
    /**
     * @var ArticleRepository
     */
    protected $repository = null;

    /**
     * 建立 100 筆假文章
     */
    protected function seedData()
    {
        for ($i = 1; $i <= 100; $i ++) {
            Article::create([
                'title' => 'title ' . $i,
                'body'  => 'body ' . $i,
            ]);
        }
    }

    // 跟前面一樣,每次都要初始化資料庫並重新建立待測試物件
    // 以免被其他 test case 影響測試結果
    public function setUp()
    {
        parent::setUp();

        $this->initDatabase();
        $this->seedData();

        // 建立要測試用的 repository
        $this->repository = new ArticleRepository();
    }

    public function tearDown()
    {
        $this->resetDatabase();
        $this->repository = null;
    }
}

測試 latest10 方法:

    public function testFetchLatest10Articles()
    {
        // 從 repository 中取得最新 10 筆文章
        $articles = $this->repository->latest10();
        $this->assertEquals(10, count($articles));

        // 確認標題是從 100 .. 91 倒數
        // "title 100" .. "title 91"
        $i = 100;
        foreach ($articles as $article) {
            $this->assertEquals('title ' . $i, $article->title);
            $i -= 1;
        }
    }

執行測試出現 Fatal error ,因為我們還沒有 latest10 方法。

app/Repositories/ArticleRepository.php 加入:

    public function latest10()
    {
    }

執行測試後紅燈,但錯誤訊息不同了,這是正常的第一步,我們還需要加入實作:

    public function latest10()
    {
        return Article::query()->orderBy('id', 'desc')->limit(10)->get();
    }

測試出現綠燈,成功。

這就是 TDD 的流程,也就是「寫測試 → 紅燈 → 寫程式 → 綠燈」。

接下來都會照這個步調來進行。

測試 create 方法:

class ArticleRepositoryTest extends TestCase
{
    // ...

    public function testCreateArticle()
    {
        // 因為前面有 100 筆了,
        // 所以這裡我們可以預測新增後的 id 是 101
        $latestId = self::POST_COUNT + 1;

        $article = $this->repositorys->create([
            'title' => 'title ' . $latestId,
            'body'  => 'body ' . $latestId,
        ]);

        $this->assertEquals(self::POST_COUNT + 1, $article->id);
    }
}

測試失敗,新增 ArticleRepository::create 方法:

    public function create(array $attributes)
    {
        return Article::create($attributes);
    }

測試成功。

results matching ""

    No results matching ""