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

Php 无法在Laravel中运行多个控制器测试,php,unit-testing,laravel,phpunit,mockery,Php,Unit Testing,Laravel,Phpunit,Mockery,我试图通过为一些遗留代码编写单元测试(并在此过程中进行更新)来清理现有的应用程序。我重写了许多库,我真的很喜欢TDD方法。然而,现在是时候继续测试一些控制器了,我在第一组测试中遇到了一个问题。我遵循杰弗里·韦的《拉威尔测试解码》中的解释 这里的目标是测试我的登录路径:http://my-development-server/login。代码应该是这样工作的:首先,检查是否有人已经登录-如果有,将他们重定向到仪表板(应用程序的主页)。否则,呈现登录页面。非常直截了当 以下是涉及的路线: Route

我试图通过为一些遗留代码编写单元测试(并在此过程中进行更新)来清理现有的应用程序。我重写了许多库,我真的很喜欢TDD方法。然而,现在是时候继续测试一些控制器了,我在第一组测试中遇到了一个问题。我遵循杰弗里·韦的《拉威尔测试解码》中的解释

这里的目标是测试我的登录路径:
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

这个问题有几个奇怪的地方:

  • 如果我注释掉第一个测试方法(
    test\u login\u alreadyLoggedIn
    ),则第二个测试通过

  • 如果我颠倒两个测试方法的顺序,
    test\u login\u notLoggedIn
    通过,而
    test\u login\u alreadyLoggedIn
    失败(即类中的第一个方法通过,第二个失败)

  • 在我看来,这似乎是某种配置问题——在第一次测试(通过)之后,出现了一些问题,无法在第二次测试中发出请求——但我不知所措。我已经在这本书和谷歌上翻了好几遍,但找不到任何我缺少的配置的参考


    有什么建议吗?

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

    这是由于我的
    routes.php
    文件出现问题造成的。特别是,我按路径组织到一组文件中:

  • accounts.php
    -包含与“account”函数相关的路由

  • admin.php
    -包含与“admin”函数相关的路由

  • 等等


  • 这些文件随后包含在我的
    routes.php
    文件中,其中包含
    require\u once
    。这对我的应用程序来说很好,但由于某些原因,在测试期间没有正确加载路由。解决方法是将我的路由移回
    routes.php
    文件,直到我找到更好的方法来组织它们。

    您可以通过将
    require\u once()
    替换为
    require()

    来解决此问题。谢谢,刚刚花了20分钟调试了相同的问题!在routes.php中将require_once()更改为require(),修复了测试问题,到目前为止,我还没有注意到其他副作用。但为什么会出现这个问题?有人能解释一下背后的逻辑吗?