在 Laravel 中对控制器进行单元测试而不测试路由的最佳方法是啥
Posted
技术标签:
【中文标题】在 Laravel 中对控制器进行单元测试而不测试路由的最佳方法是啥【英文标题】:What's the best way to unit test a controller in Laravel without testing the route too在 Laravel 中对控制器进行单元测试而不测试路由的最佳方法是什么 【发布时间】:2013-10-02 12:19:33 【问题描述】:我已经阅读了很多关于使用 $this->call($destination, $parameters, 'GET');
测试控制器的文档,但这似乎也依赖于设置的路由,并且知道使用正确的 $destination
。
通常这没问题,但从路由访问控制器似乎不适用于单元测试。我想对控制器进行单元测试,而不是路由。有没有不处理路由的单元测试控制器的标准方法?
仅仅手动实例化控制器并调用方法就足够了吗?例如
$controller = new MyController;
$response = $controller->someMethod($param);
$this->assertSomething($response);
也许控制器不应该进行单元测试(只有验收测试),我的请求表明我的控制器太重了。
【问题讨论】:
可能,可能,也许。并不是说我很了解 Laravel,而是您可以自己尝试的第一个问题 - 只是实例化控制器。如果 Laravel 涉及到一些服务容器,并且如果你的控制器使用它,那么你可能需要模拟一些协作者,但也许你可以将它们封装在它自己的 TestCase 中并从它扩展以保持单元测试控制器更帅。但是写测试就像写代码一样,如果行得通,你也需要尝试。 到目前为止,实例化控制器似乎工作正常,但我担心这不是“Laravel 方式”。我正在从 Laravel 扩展我的测试用例,它会自动设置“应用”DIC。 好吧,如果它为 DIC 应用程序设置了测试双打,这对于测试来说可能是可以的。如果不是,那么事情可能会变得可疑。你可能应该在 Laravel IRC 聊天中讨论一下这个问题,我可以想象那里需要这种反馈。那里的人应该能够告诉你更多关于 Laravel 的细节,然后我可以做到。 【参考方案1】:您可以直接调用您的操作:
$response = $this->action('GET', 'OrdersController@show', ['id' => 1]);
【讨论】:
这是一个很好的步骤。我是否必须知道正确的 HTTP 方法(例如GET
)?
是的,testcase 的 action 方法需要 HTTP 方法,你应该在测试中彻底,所以这也是一个很好的做法。
我的观点是控制器(例如OrdersController::show()
)不应该与路由的HTTP方法耦合,也不应该知道它。
@AntonioCarlosRibeiro ,它不适合我吗?我该怎么办?
@AntonioCarlosRibeiro 我有一个问题:我正在一个环境中工作,控制器名称有时会因不同的构建而改变,但路由目的地永远不会改变。因此,想象一个具有数百条路由和不同控制器的巨大应用程序,并对每个控制器进行测试。我想知道是否有办法让$this->call('POST', users, ['id' =>1]);
用户成为来自Route::resource('users', UsersRestfulController', array('only' => array('index', 'show', 'store', 'update')));
的指定路线我想要这样,以便当控制器发生变化时,测试可维护性IsANoBrainer
【参考方案2】:
action
方法已从 Laravel 5.4 testing api 中删除
【讨论】:
【参考方案3】:在 laravel 6 中任何控制器方法都可以直接调用如下:
app()->call('App\Http\Controllers\TestController@testMethod', [$param1, $param2]);
就是这样。
【讨论】:
以上是关于在 Laravel 中对控制器进行单元测试而不测试路由的最佳方法是啥的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Cordapp 中对服务和控制器(kotlin)进行单元测试?
如何在 Service 构造函数中对 Controller 进行单元测试和模拟 @InjectModel
在 vuejs + laravel 中使用 jest 进行单元测试