前言
本文參考〈如何測試內含相依物件的函式〉一文,對先前〈在 Laravel 5.6 使用 Repository 與 Service Container〉一文之實作進行測試。
環境
- Windows 10
- Homestead 7.4.1
新增資源庫
在資源庫新增一個 getAllPackages()
方法,以取得資料庫的所有 Packages。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| namespace App\Repositories;
use App\Contracts\PackageInterface; use App\Package;
class PackageRepository implements PackageInterface { protected $package;
public function __construct(Package $package) { $this->package = $package; }
public function getAllPackages() { $packages = $this->package->all();
return $packages; } }
|
新增控制器
在 PackageController
新增 getAllPackages()
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| namespace App\Http\Controllers;
use App\Contracts\PackageInterface;
class PackageController extends Controller { protected $package;
public function __construct(PackageInterface $package) { $this->package = $package; }
public function index() { $packages = $this->package->getAllPackages();
return view('package.index', compact('packages')); } }
|
測試
編輯 tests\TestCase.php
檔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use Mockery;
abstract class TestCase extends BaseTestCase { use CreatesApplication;
public function initMock($class) { $mock = Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock; } }
|
在 tests\Feature
新增 PackageControllerTest.php
檔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| namespace Tests\Feature;
use Tests\TestCase; use App\Contracts\PackageInterface; use App\Http\Controllers\PackageController; use Illuminate\Database\Eloquent\Collection; use Mockery;
class PackageControllerTest extends TestCase { protected $mock;
protected $target;
public function setUp() { parent::setUp();
$this->mock = $this->initMock(PackageInterface::class);
$this->target = $this->app->make(PackageController::class); }
public function testIndex() { $expected = new Collection([ ['name' => 'Name 1', 'html_url' => 'HTML URL 1'], ['name' => 'Name 2', 'html_url' => 'HTML URL 2'], ['name' => 'Name 3', 'html_url' => 'HTML URL 3'], ]);
$this->mock ->shouldReceive('getAllPackages') ->once() ->andReturn($expected);
$actual = $this->target->index()->packages;
$this->assertEquals($expected, $actual); }
public function tearDown() { $this->mock = null; $this->target = null; } }
|
單元測試的 3A 原則
Arrange
準備測試資料 $fake
、mock
物件 $mock
、待測物件 $target
,與建立測試期望値 $expected
。
Act
執行待測物件的 method
,與建立實際結果値 $actual
。
Assert
使用 PHPUnit 的斷言函式測試 $expected
與 $actual
是否如預期。