Laravel 测试。测试时重置控制器 DI

Posted

技术标签:

【中文标题】Laravel 测试。测试时重置控制器 DI【英文标题】:Laravel testing. Reset controller DI while test 【发布时间】:2019-06-19 01:15:21 【问题描述】:

我有一个带有 DI 的 Laravel 控制器

__construct(Model1 $m1, Model2 $m2, $SomeService $s) 
 $this->m1 = $m1;
 $this->m2 = $m2;
 $this->s = $s;

我有一个基于此控制器的调用或端点 API 测试。我正在使用不同的有效负载进行 8 个相同的 API url 调用。似乎 z 控制器构造函数处理 1 次,然后处理构造的依赖项。

$response1 = $this->actingAs($admin,'api')->json('POST', '/api/someURL', $payload1);

$response2 = $this->actingAs($admin,'api')->json('POST', '/api/someURL', $payload2);

$responseN = $this->actingAs($admin,'api')->json('POST', '/api/someURL', $payloadN);

我可以在测试中的每个 API 调用之前以某种方式设置依赖关系吗?

【问题讨论】:

会不会SomeService注册为单例? SomeService 只是 App\Providers 中的一个用户类; @Amade 我的意思是,我在这门课上并没有什么特别之处...... 各位,使用 Mockery 怎么样? 【参考方案1】:

您可以使用以下方法在路由请求之间取消设置控制器实例:

$response1 = $this->actingAs($admin,'api')->json('POST', '/api/someURL', $payload1);

// unset the controller
$this->app->get(Illuminate\Routing\Route::class)->controller = null;

$response2 = $this->actingAs($admin,'api')->json('POST', '/api/someURL', $payload2);

// unset the controller
$this->app->get(Illuminate\Routing\Route::class)->controller = null;

$responseN = $this->actingAs($admin,'api')->json('POST', '/api/someURL', $payloadN);

为什么?

在Illuminate\Routing\RouterLaravel 将当前路由绑定到容器中:

protected function findRoute($request)

    $this->current = $route = $this->routes->match($request);
    $this->container->instance(Route::class, $route);
    return $route;

当路由控制器在Illuminate\Routing\Route中运行时,控制器实例存储在Route对象中:

public function getController()

    if (! $this->controller) 
        $class = $this->parseControllerCallback()[0];
        $this->controller = $this->container->make(ltrim($class, '\\'));
    
    return $this->controller;

【讨论】:

Illuminate\Container\EntryNotFoundException: E:\repos\dcp-laravel\vendor\laravel\framework\src\Illuminate\Container\Container.php:613 E:\repos\dcp-laravel\tests \Unit\ProposalRoundTest.php:183 我希望你不要让我直接在 Illuminate\ 文件夹中进行更改?) 不,后面的部分只是答案背后的推理。 在你至少打过一次路线后,你还在做$this->app->get(Route::class)->controller = null;吗? 好的,它有效。但无论如何,它看起来有点作弊)我已经预料到像这样的嘲弄或smth......

以上是关于Laravel 测试。测试时重置控制器 DI的主要内容,如果未能解决你的问题,请参考以下文章

Laravel phpunit 测试控制器,它返回带有数据的视图

Laravel 5 使用 phpUnit 进行测试而不重置我的数据库

在 laravel 5.4 中测试文件上传时出错

Laravel - 输入未通过单元测试

Laravel 单元测试 - 控制器

在 Laravel 中对控制器进行单元测试而不测试路由的最佳方法是啥