簡體   English   中英

使用Laravel模型綁定模擬控制器測試

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM