[英]Mocking Laravel controller dependency
在我的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
}
您可以模擬存儲庫類並將其加載到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中運行良好。
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方法上。
希望這是有幫助的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.