[英]Mocking in controller tests with Laravel model binding
我在路由中使用模型綁定將模型傳遞到控制器動作中,並希望能夠編寫測試。 如果不需要測試就可以訪問數據庫,那將是更好的選擇。
在此示例中,使用用戶名綁定模型,然后在路由的定義中使用該模型。
// routes.php
Route::model('user', function($value, $route)
{
return User::whereUsername($value)->firstOrFail();
});
Route::get('users/{user}', 'UsersController@show');
在我的控制器中,綁定的用戶被傳遞到操作。
// UsersController.php
function show(User $user)
{
return View::make('users.show', compact('user');
}
現在,在測試中,我試圖模擬用戶。
// UsersControllerTest.php
public function setUp()
{
parent::setUp();
$this->mock = Mockery::mock('Eloquent', 'User');
$this->app->instance('User', $this->mock);
}
public function testShowPage()
{
$this->mock->shouldReceive('whereSlug')->once()->andReturn($this->mock);
$this->action('GET', 'UsersController@show');
$this->assertResponseOk();
$this->assertViewHas('user');
}
運行此測試時,出現以下錯誤:
ErrorException: Argument 1 passed to UsersController::show() must be an instance of User, instance of Illuminate\Database\Eloquent\Builder given
我還希望能夠使用return User::firstByAttribtues($value);
但是Mockery不會讓我嘲笑一個受保護的方法-有什么辦法可以解決這個問題?
我必須通過Mockery的源代碼進行挖掘才能找到它,但是您是否看過shouldAllowMockingProtectedMethods嗎?
即,模擬類foo並允許模擬受保護的方法:
$bar = \Mockery::mock('foo')->shouldAllowMockingProtectedMethods();
// now set your expectations up
然后繼續往那走。
不知道為什么沒有收到像意外方法“ firstOrFail”那樣的錯誤。 但是,乍一看,我認為問題在於在route.php中定義的模型路由也正在調用firstOrFail方法。
因此,您的測試應如下所示:
public function testShowPage()
{
$stubQuery = \Mockery::mock('Illuminate\Database\Eloquent\Builder');
$this->mock->shouldReceive('whereSlug')->once()->andReturn($stubQuery);
$stubQuery->shouldReceive('firstOrFail')->andReturn($this->mock);
$this->action('GET', 'UsersController@show');
$this->assertResponseOk();
$this->assertViewHas('user');
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.