模拟 Laravel 控制器依赖
Posted
技术标签:
【中文标题】模拟 Laravel 控制器依赖【英文标题】:Mocking Laravel controller dependency 【发布时间】:2015-10-21 15:52:02 【问题描述】:在我的 Laravel 应用程序中,我有一个控制器,它具有显示特定资源的方法。例如。说 url 是 /widgets/26
我的控制器方法可能像这样工作:
Class WidgetsController
protected $widgets;
public function __construct(WidgetsRepository $widgets)
$this->widgets = $widgets;
public function show($id)
$widget = $this->widgets->find($id);
return view('widgets.show')->with(compact('widget'));
我们可以看到我的WidgetsController
有一个WidgetsRepository
依赖项。在show
方法的单元测试中,如何模拟此依赖项,以便我实际上不必调用存储库,而只需返回硬编码的widget
?
单元测试开始:
function test_it_shows_a_single_widget()
// how can I tell the WidgetsController to be instaniated with a mocked WidgetRepository?
$response = $this->action('GET', 'WidgetsController@show', ['id' => 1]);
// somehow mock the call to the repository's `find()` method and give a hard-coded return value
// continue with assertions
【问题讨论】:
【参考方案1】:您可以模拟存储库类并将其加载到 IoC 容器中。
所以当 Laravel 到达你的控制器时,它会发现它已经在那里,并且会解析你的模拟而不是实例化一个新的。
function test_it_shows_a_single_widget()
// mock the repository
$repository = Mockery::mock(WidgetRepository::class);
$repository->shouldReceive('find')
->with(1)
->once()
->andReturn(new Widget([]));
// load the mock into the IoC container
$this->app->instance(WidgetRepository::class, $repository);
// when making your call, your controller will use your mock
$response = $this->action('GET', 'WidgetsController@show', ['id' => 1]);
// continue with assertions
// ...
类似的设置已经在 Laravel 5.3.21 中进行了测试并且运行良好。
【讨论】:
【参考方案2】:在 Laracasts 上有一个类似的问题。这个人有这样的事情(https://laracasts.com/discuss/channels/general-discussion/mockery-error?page=1):
public function testMe()
// Arrange
$classContext = Mockery::mock('\FullNamespace\To\Class');
$classContext->shouldReceive('id')->andReturn(99);
$resources = new ResourcesRepo($classContext);
// Act
// Assert
如果使用 phpUnit 方法 (http://docs.mockery.io/en/latest/reference/phpunit_integration.html),您也可以将它放在 setUp 方法中。
希望这有帮助。
【讨论】:
以上是关于模拟 Laravel 控制器依赖的主要内容,如果未能解决你的问题,请参考以下文章
Windows下Composer依赖控制器下载纯净版laravel
Laravel 服务容器 IoC(控制反转) 和 DI(依赖注入)