如何测试Laravel 5中的路线,或尝试"MockStub"的东西,或者我不知道TDD

Alv*_*eda 3 unit-testing routes mockery laravel-5

我从TDD和Laravel开始.具体来说,我是从路线开始的.我定义了一些并且我定义得很糟糕,因为我对TDD的"新"概念感到兴奋,我想为它们编写一些测试.

我的想法是单独测试路线和路线,就像我对TDD推荐的所有内容一样.我知道我可以做一个$this->call->('METHOD','something')测试响应是好的或者其他什么,但我想知道正确的控制器的正确方法被调用.

所以,我以为我可以嘲笑控制器.这是我的第一次尝试:

public function test_this_route_work_as_expected_mocking_the_controller()
{
    //Create the mock
    $drawController = \Mockery::mock('App\Http\Controllers\DrawController');
    $drawController->shouldReceive('show')->once();

    // Bind instance of my controller to the mock
    App::instance('App\Http\Controllers\DrawController', $drawController);

    $response = $this->call('GET','/draw/1');

    // To see what fails. .env debugging is on
    print($response);
}
Run Code Online (Sandbox Code Playgroud)

路线是Route::resource('draw', 'DrawController');,我知道没关系.但是没有调用方法show.在响应中可以看到:"此模拟对象上不存在方法Mockery_0_App_Http_Controllers_DrawController :: getAfterFilters()".所以我试着:

$drawController->getAfterFilters()->willReturn(array());
Run Code Online (Sandbox Code Playgroud)

但我得到:

BadMethodCallException: Method Mockery_0_App_Http_Controllers_DrawController::getAfterFilters() does not exist on this mock object
Run Code Online (Sandbox Code Playgroud)

经过一些测试,我能够达到这个解决方案:

public function test_this_route_work_as_expected_mocking_the_controller_workaround()
{
    //Create the mock
    $drawController = \Mockery::mock('App\Http\Controllers\DrawController');
    // These are the methods I would like to 'stub' in this mock
    $drawController->shouldReceive('getAfterFilters')->atMost(1000)->andReturn(array());
    $drawController->shouldReceive('getBeforeFilters')->atMost(1000)->andReturn(array());
    $drawController->shouldReceive('getMiddleware')->atMost(1000)->andReturn(array());
    // This is where the corresponding method is called. I can assume all is OK if we arrive here with
    // the right method name:
    // public function callAction($method, $parameters)
    $drawController->shouldReceive('callAction')->once()->with('show',Mockery::any());

    // Bind instance of my controller to the mock
    App::instance('App\Http\Controllers\DrawController', $drawController);

    //Act
    $response = $this->call('GET','/draw/1');
}
Run Code Online (Sandbox Code Playgroud)

但我想改变shouldReceiveswillReturns:将atMost(1000)正在伤害我的眼睛.所以我的问题是:

1)是否有更简洁的方法来测试Laravel 5中的路线?我的意思是,理想情况将是控制器不存在的情况,但是,如果路线正常,则测试会进行调整

2)是否可以"MockStub"控制器?有什么更好的方法呢?

非常感谢你.

Alv*_*eda 9

我终于明白了.你需要部分模拟.它可以像这样简单(诀窍包括模拟到Mockery :: mock的方法的"数组"):

public function test_this_route_work_as_expected_mocking_partially_the_controller()
{
    //Create the mock
    $drawController = \Mockery::mock('App\Http\Controllers\DrawController[show]');
    $drawController->shouldReceive('show')->once();

    // Bind instance of my controller to the mock
    App::instance('App\Http\Controllers\DrawController', $drawController);

    //Act
    $this->call('GET','/draw/1');
}
Run Code Online (Sandbox Code Playgroud)

并且,如果您在setup()方法中创建所有控制器的部分模拟,则所有路径测试可以分组在一个(或几个)TestCases中