依赖注入

依赖注入与测试

昨天介绍了 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


<<:  Angular Stock登入(二)(Day22)

>>:  Day 22 - Memorized Hook: useMemo

3.移转 Aras PLM大小事-Agile 汇出 Part & BOM (1)

第3话 Agile 汇出 Part & BOM(1) 想要汇出Agile的Part与BOM,...

为了转生而点技能-JavaScript,day8(浅笔记-物件之浅层复制与深层复制

物件复制: 浅层复制(shallow copy):仅被复制的一方能保留第一层的物件之值,但是当复制方...

Day17:终於要进去新手村了-Javascript-回圈-while简单举例练习

今天看了彭彭老师的影片,他使用了程序码做举例,这篇我会使用他举例的程序,再另外加上自己笔记让印象加深...

【图解演算法教学】一次搞懂「资料结构」与「演算法」到底是什麽?

Youtube连结:https://bit.ly/35x3dih 这次我们将精确定位出,在整个演算...

海棠小姐借我一根头发, 轻轻的拉~拉~拉~ - 盘中 call 讯

写好一些买卖讯号之後,除了可以用回测之外,也可以工人智慧协助查看是否与其策略符合 研究了一下 结合聊...