Laravel单元测试控制器

atm*_*tmd 13 php phpunit unit-testing laravel-4

我试图在TDD之后开始一个新的Laravel应用程序

我的第一步是检查主页上是否调用了/ login控制器.

尽管遵循了几个教程我无法让测试工作,但我根本无法看到我做错了什么.

我的设置是:作曲家安装laravel composer来安装phpunit

这是我的路线:

<?php
Route::get('/login', 'AuthenticationController@login');
Run Code Online (Sandbox Code Playgroud)

我的控制器:

<?php

class AuthenticationController extends BaseController {

    public function login () {
        return View::make('authentication.login');
    }

}
Run Code Online (Sandbox Code Playgroud)

我的测试:

<?php

class AuthenticationTest extends TestCase {

    public function testSomeTest () {

        $response = $this->action('GET', 'AuthenticationController@login');

        $view = $response->original;

        $this->assertEquals('authentication.login', $view['name']);
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是

  ErrorException: Undefined index: name
Run Code Online (Sandbox Code Playgroud)

代码作为一个副本(几乎完全)来自Laravel网站,但它没有运行.

谁能看到我做错了什么?

它声称$ view没有索引名称,但这不能正确,因为它在laravel网站上的示例,加上视图正在使用其名称呈现(它也在前端正确显示)

编辑::

因此,从评论中可以看出,laravel单元测试部分不清楚,$ view ['name']正在检查名为$ name的变量.如果是这种情况,您如何测试使用的控制器/路由,IE.什么控制器名称/操作名称已用于路由('X')

Qua*_*unk 20

好的,正如评论中已经解释的那样,让我们​​先退一步思考一下这个场景.

"我的第一步是检查主页上是否调用/ login控制器."

这意味着:当用户点击归属路由时,您想要检查用户是否已登录.如果不是,则需要将其重定向到登录,可能还有一些flash消息.登录后,您需要将它们重定向回主页.如果登录失败,您希望将它们重定向回登录表单,也可以使用flash消息.

所以现在要测试几件事:家庭控制器和登录控制器.因此,遵循TDD精神,让我们首先创建测试.

注意:我将遵循phpspec使用的一些命名约定,但不要让你烦恼.

class HomeControllerTest extends TestCase
{
    /**
     * @test
     */
    public function it_redirects_to_login_if_user_is_not_authenticated()
    {
        Auth::shouldReceive('check')->once()->andReturn(false);

        $response = $this->call('GET', 'home');

        // Now we have several ways to go about this, choose the
        // one you're most comfortable with.

        // Check that you're redirecting to a specific controller action 
        // with a flash message
        $this->assertRedirectedToAction(
             'AuthenticationController@login', 
             null, 
             ['flash_message']
        );

        // Only check that you're redirecting to a specific URI
        $this->assertRedirectedTo('login');

        // Just check that you don't get a 200 OK response.
        $this->assertFalse($response->isOk());

        // Make sure you've been redirected.
        $this->assertTrue($response->isRedirection());
    }

    /**
     * @test
     */
    public function it_returns_home_page_if_user_is_authenticated()
    {
        Auth::shouldReceive('check')->once()->andReturn(true);

        $this->call('GET', 'home');

        $this->assertResponseOk();
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是Home控制器.在大多数情况下,您实际上并不关心重定向到哪里,因为这可能会随着时间而改变,您必须更改测试.因此,您应该做的最少的事情是检查您是否被重定向,如果您认为这对您的测试很重要,则只检查更多详细信息.

我们来看看身份验证控制器:

class AuthenticationControllerTest extends TestCase
{
    /**
     * @test
     */
    public function it_shows_the_login_form()
    {
        $response = $this->call('GET', 'login');

        $this->assertTrue($response->isOk());

        // Even though the two lines above may be enough,
        // you could also check for something like this:

        View::shouldReceive('make')->with('login');
    }

    /**
     * @test
     */
    public function it_redirects_back_to_form_if_login_fails()
    {
        $credentials = [
            'email' => 'test@test.com',
            'password' => 'secret',
        ];

        Auth::shouldReceive('attempt')
             ->once()
             ->with($credentials)
             ->andReturn(false);

        $this->call('POST', 'login', $credentials);

        $this->assertRedirectedToAction(
            'AuthenticationController@login', 
            null, 
            ['flash_message']
        );
    }

    /**
     * @test
     */
    public function it_redirects_to_home_page_after_user_logs_in()
    {
        $credentials = [
            'email' => 'test@test.com',
            'password' => 'secret',
        ];

        Auth::shouldReceive('attempt')
             ->once()
             ->with($credentials)
             ->andReturn(true);

        $this->call('POST', 'login', $credentials);

        $this->assertRedirectedTo('home');
    }
}
Run Code Online (Sandbox Code Playgroud)

再一次,总是想想你真正想要测试的东西.你真的需要知道在哪条路线上触发了哪个控制器动作?或者返回视图的名称是什么?实际上,您只需要确保控制器实际上尝试这样做.您传递一些数据,然后测试它是否按预期运行.

并且始终确保您不尝试测试任何框架功能,例如,如果特定路由触发特定操作或者View正确加载.这已经过测试,因此您无需担心.专注于应用程序的功能而不是底层框架.