本文介绍了如何在Laravel 5中测试路线,或尝试"MockStub"东西,或者我不知道TDD的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从TDD和Laravel开始.具体来说,我从路线开始.我定义了一些,但定义却很糟糕,当我对TDD的新"概念感到非常兴奋时,我想为他们编写一些测试.

I'm starting with TDD and Laravel. Specifically, I'm starting with routes. I defined some and I defined it badly, so excited as I was with the "new" concept of TDD I wanted to write some test for them.

我的想法是测试路由,并且仅对路由进行隔离测试,因为我所读到的有关TDD的所有内容都值得推荐.我知道我可以执行$this->call->('METHOD','something')并且测试响应是可以的,但是我想知道正确的控制器的正确方法被调用.

The idea was to test the routes and only the routes, in isolation, as everything I've readed about TDD recomends. I know I can do a $this->call->('METHOD','something') and test response is OK or whatever, but I would like to know that the right method of the right controller is called.

所以,我认为我可以模拟控制器.这是我的第一次尝试:

So, I thought that I could mock the controller. This was my first attempt:

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);
}

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

The route is Route::resource('draw', 'DrawController');, I know it's ok. But method show is not called. In the response it can be seen: "Method Mockery_0_App_Http_Controllers_DrawController::getAfterFilters() does not exist on this mock object". So I tried to:

$drawController->getAfterFilters()->willReturn(array());

但是我得到了

BadMethodCallException: Method Mockery_0_App_Http_Controllers_DrawController::getAfterFilters() does not exist on this mock object

经过一些测试,我能够得到以下解决方案:

After some testing, I was able to arrive to this solution:

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');
}

但是我想将shouldReceives更改为willReturns:atMost(1000)伤害了我的眼睛.所以我的问题是:

But I would like to change the shouldReceives for willReturns: the atMost(1000) are hurting my eyes. So the questions I have are:

1)是否有一种更干净的方法可以仅测试Laravel 5中的路线?我的意思是,理想的情况是不存在控制器的情况,但是,如果路由正常,则进行测试.

1) Is there a cleaner way to test ONLY the routes in Laravel 5? I mean, the ideal scenario will be one in which the controller doesn't exist but, if the route is ok, the test pases

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

2) Is it possible to "MockStub" the controllers? What's the better way to do it?

非常感谢您.

推荐答案

我终于明白了.您需要部分模拟.可以如此简单地完成(技巧是包括一个模拟方法来模拟Mockery :: mock的数组"):

I've finally got it. You need a partial mock. It can be done as simple as this (the trick is including an "array" of methods to mock to 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');
}

并且,如果您使用setup()方法创建了所有控制器的部分模拟,则所有路由测试都可以归为一个(或几个)TestCases中.

And, if you create a partial mock of all controllers in setup() method, all route tests can be grouped in a single (or a couple) of TestCases

这篇关于如何在Laravel 5中测试路线,或尝试"MockStub"东西,或者我不知道TDD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 09:20