在laravel测试中调用命名路由

时间:2016-01-03 21:48:52

标签: unit-testing testing laravel-5 phpunit laravel-5.2

考虑以下事项:

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class HomeRouteTest extends TestCase
{
    public function testVisitTheHomePage()
    {
        $response = $this->call('GET', '/');
        $this->assertEquals(200, $response->status());

    }

    public function testVisitTheAboutPage()
    {
        $response = $this->call('GET', '/about');
        $this->assertEquals(200, $response->status());
    }
}

离开了,而不是我见过记录的&gt;。&gt;,做了类似的事情:

$response = $this->call('GET', 'home.about');
$this->assertEquals(200, $response->status());

或......你是怎么做到的?

我得到的错误是:

vagrant@scotchbox:/var/www$ phpunit
PHPUnit 4.8.21 by Sebastian Bergmann and contributors.

FF

Time: 3.41 seconds, Memory: 14.25Mb

There were 2 failures:

1) HomeRouteTest::testVisitTheHomePage
Failed asserting that 404 matches expected 200.

/var/www/tests/HomeRouteTest.php:12

2) HomeRouteTest::testVisitTheAboutPage
Failed asserting that 404 matches expected 200.

/var/www/tests/HomeRouteTest.php:19

FAILURES!
Tests: 2, Assertions: 2, Failures: 2.

3 个答案:

答案 0 :(得分:4)

这是一个非常晚的回应,但我认为您正在寻找的是:

$this->route('GET', 'home.about');
$this->assertResponseOk(); // Checks that response status was 200

对于带参数的路线,您可以这样做:

$this->route('GET', 'users.show', ['id' => 3]); // (goes to '/users/3')

我需要这个来测试我正在使用的一些可怕的路线,看起来像这样:

Route::resource(
    '/accounts/{account_id}/users',
    'AccountsController@users',
    [
        'parameters' => ['account_id'],
        'names'      => [
            'create'  => 'users.create',
            'destroy' => 'users.destroy',
            'edit'    => 'users.edit',
            'show '   => 'users.show',
            'store'   => 'users.store',
            'update'  => 'users.update',
        ]
    ]
);

为了确保我的路线和重定向转到了正确的页面,我这样做了:

/**
 * @test
 */
public function users_index_route_loads_correct_page()
{
    $account = Account::first();

    $response = $this->route('get', 'users.index', ['account_id' => $account->id]);
    $this->assertResponseOk()
        ->seePageIs('/accounts/' . $account->id . '/users');
}

为了确保我使用正确的视图文件(我们都制作了复制粘贴错误,对吧?),我这样做了:

/**
 * @test
 */
public function users_index_route_uses_expected_view()
{
    $account = Account::first();

    $response = $this->route('get', 'users.index', ['account_id' => $account->id]);

    $view = $response->original; // returns View instance
    $view_name = $view->getName();

    $this->assertEquals($view_name, 'users.index'); 
}

如果不是PHPStorm中的Structure功能和Laravel 4.2的文档,我偶然发现,我认为我不会想到如何测试这些路由。我希望这能节省一些时间。

答案 1 :(得分:0)

据我所知,该解决方案适用于任何Laravel 5版本。特别是Laravel 5.4+与这里提到的其他解决方案不同。

如果您的命名路由具有参数,则可以执行以下操作:

$response = $this->get(route('users.show', [
    'user' => 3,
]));

$response->assertStatus(200);

如果您的命名路由没有参数,则可以执行以下操作:

$response = $this->get(route('users.index'));

$response->assertStatus(200);

好又简单。

答案 2 :(得分:-2)

说实话,我认为没有任何理由来测试名字路线。命名路由更适合在应用程序内部使用,您应该测试具体URL而不是名称路由以确保使用正确的URL。

如果你需要真正测试命名路由,我会用简单数组创建辅助函数:

protected function getNamedRoute($name) 
{
   $routes = [
        'home.about' => '/about',
   ];

   return $routes[$name]; 
}

然后在你的测试中:

public function testVisitTheHomePage()
{
    $response = $this->call('GET', $this->getNamedRoute('home.about'));
    $this->assertEquals(200, $response->status());
}

第二件事是你可以让这些测试更清洁,你不需要使用:

$response = $this->call('GET', '/');
$this->assertEquals(200, $response->status());

你可以使用:

$this->visit('/')->seeStatusCode(200);

对我而言,它更清晰,您可以编写更少的代码来实现相同目标。