iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0

依賴注入與測試

昨天介紹了 Laravel 的 Service Container ,其主要的功能就是建立創建類別實例的捷徑,而 Laravel 藉由這個功能實現了依賴注入的架構。

至於何為依賴注入呢? 首先看看下面的例子

use App\Services\TodoService;

class TodoController extends Controller
{
    protected $todoService;

    public function __construct(
        TodoService $todoService, 
    ) {
        $this->todoService = $todoService; 
    }
 
    //...
}

當 TodoController 被建立的時候,我們藉由 Service Container 創建了 TodoService 的實例並傳入,然後把這個實例賦予為 TodoController 的內部屬性。

接著我們就能在 TodoController 中藉由這個內部屬性使用 TodoService 實例的函式

class TodoController extends Controller
{

    //...

    public function store(Request $request)
    {
        $data = $request->all(); 

        $this->todoService->create([
            'name' => $data['name']
        ]);
 
    }
}

這種在外部創建類別實例當作參數傳入類別的做法就稱為依賴注入,相反的作法就是在類別內部創建實例。

use App\Services\TodoService;

class TodoController extends Controller
{
    protected $todoService;

    public function __construct() {
        $todoService = new TodoService;
        $this->todoService = $todoService; 
    }
 
    //...
}

這種做法的壞處在於 TodoController 是直接依賴於 TodoService 這個類別,導致沒辦法輕易的替換掉 TodoService 。

這樣在進行測試的時候就很傷腦筋了,只是想做 TodoController 的單元測試卻必須先確保 TodoService 能正常運作,才能夠進行測試。

這時候就顯現出 Service Container 與依賴注入的優點了,當我們要測試時,先在 Service Container 註冊 TodoService::class 的實例為 Mock 版的,就不用擔心測試會受 TodoService 的功能所影響了。

use App\Services\TodoService;
use Mockery; 

public function test_with_mocked_instance()
{
    $this->instance(
        TodoService::class,
        Mockery::mock(TodoService::class)
    );
}

依賴注入與介面

前面都注入的都是類別,但在 Service Container 中我們也可以注入介面,只要有先註冊好介面對應的實作類別就好。

use App\Contracts\EventPusher;
use App\Services\RedisEventPusher;

$this->app->bind(EventPusher::class, RedisEventPusher::class);
use App\Contracts\EventPusher;

public function __construct(EventPusher $pusher)
{
    $this->pusher = $pusher;
}

好玩的在於,我們可以隨時替換註冊的實作類別,整組整組的替換掉功能。

use App\Contracts\EventPusher;
use App\Services\SqlEventPusher;

$this->app->bind(EventPusher::class, SqlEventPusher::class);

程式碼裡的 EventPusher 通通不用動,只要改一行程式碼就好。

這就是依賴注入帶來的彈性,善用的話可以極大的幫助測試與維護作業。

References

Laravel - Test Mocking


上一篇
Service Container
下一篇
Facades
系列文
Laravel 實務筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言