无法在Laravel中运行多个控制器测试

时间:2014-05-01 23:03:26

标签: php unit-testing laravel phpunit mockery

我试图通过编写一些遗留代码的单元测试来清理现有的应用程序(并在此过程中进行更新)。我重写了一些图书馆,我真的很喜欢TDD方法。但是,现在是时候继续测试一些控制器了,而且我在第一组测试中遇到了问题。我跟随了Jeffery Way的 Laravel Testing Decoded 中的解释。

此处的目标是测试我的登录路线:http://my-development-server/login。代码应该像这样工作:首先,检查某人是否已经登录 - 如果是,则将它们重定向到仪表板(应用程序中的主页)。否则,渲染登录页面。很直接。

以下是涉及的路线:

Route::get('login', array(
        'as'        => 'login',
        'uses'      => 'MyApp\Controllers\AccountController@getLogin',
    ));

Route::get('/', array(
        'as'        => 'dashboard',
        'uses'      => 'MyApp\Controllers\DashboardController@showDashboard',
        'before'    => 'acl:dashboard.view',
    ));

这是AccountController::getLogin方法:

public function getLogin()
{
    // Are we logged in?
    if (\Sentry::check())
        return Redirect::route('dashboard');

    // Show the page.
    return View::make('account.login');
}

我使用Sentry库进行用户身份验证。

这是我的第一次测试:

class AccountControllerTest extends TestCase {

    public function tearDown()
    {
        Mockery::close();
    }

    public function test_login_alreadyLoggedIn()
    {
        // arrange
        //
        \Sentry::shouldReceive("check")
            ->once()
            ->andReturn(true);

        // act
        //
        $response = $this->call("GET", "/login");

        // assert
        //
        $this->assertRedirectedToRoute("dashboard");
    }
}

此测试模拟"用户在他们已登录后尝试登录"案件。 check返回true(已登录),用户被重定向到名为dashboard的路由。它运作完美,测试通过。

接下来,我添加一个新测试,以测试用户在没有人登录时尝试登录"案件。这是该测试的代码:

public function test_login_notLoggedIn()
{
    // arrange
    //
    \Sentry::shouldReceive("getUser")
        ->twice()
        ->andReturn(null);

    \Sentry::shouldReceive("check")
        ->once()
        ->andReturn(false);

    // act
    //
    $response = $this->client->request("GET", "/login");

    // assert
    //
    $h2 = $response->filter("h2");

    $this->assertEquals("Please sign in", $h2->text());
}

当我运行此测试时,第一个测试通过,但我在第二个测试方法中得到NotFoundHttpException

这个问题有几个奇怪的事情:

  1. 如果我注释掉第一个测试方法(test_login_alreadyLoggedIn),则第二次测试通过。

  2. 如果我颠倒了两种测试方法的顺序,test_login_notLoggedIn传递并且test_login_alreadyLoggedIn失败(即,类中的第一个方法通过,第二个方法失败)。

  3. 这看起来像某种配置问题 - 在第一次测试(通过)之后,某些东西搞砸了,它无法在第二次测试中提出请求 - 但我感到茫然。我已经多次浏览了这本书并且谷歌但是找不到任何我错过的配置的参考。

    有什么建议吗?

2 个答案:

答案 0 :(得分:5)

对于任何可能在将来遇到此问题的人......

这是由我routes.php文件的问题引起的。特别是,我通过路由组织成一组文件:

  1. accounts.php - 包含与“帐户”功能相关的路线

  2. admin.php - 包含与“admin”功能相关的路线

  3. 等...

  4. 然后,我的routes.php文件中包含require_once这些文件。这适用于我的应用程序,但由于某种原因,路由未在测试期间正确加载。解决方案是将我的路由移回routes.php文件,直到找到更好的方式来组织它们。

答案 1 :(得分:2)

您可以将require_once()替换为require()

来解决此问题