0

我正在尝试通过为一些遗留代码编写单元测试(并在此过程中对其进行更新)来清理现有应用程序。我重写了许多库,我真的很喜欢 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失败(即类中的第一个方法通过,第二个失败)。

在我看来,这像是某种配置问题——在第一次测试(通过)之后,有些东西搞砸了,它无法在第二次测试中发出请求——但我不知所措。我已经多次翻阅这本书和谷歌,但找不到任何我缺少的配置的参考。

有什么建议么?

4

2 回答 2

5

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

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

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

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

  3. ETC...

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

于 2014-05-05T14:50:11.467 回答
2

您可以通过替换您的require_once()to来解决此问题require()

于 2014-07-13T03:43:28.997 回答