我正在嘗試通過爲某些遺留代碼編寫單元測試(並沿途更新它)來清理現有應用程序。我重寫了一些圖書館,我真的很喜歡TDD方法。但是,現在是時候繼續測試一些控制器,並且在第一組測試中遇到了問題。我遵循Jeffery Way的Laravel Testing Decoded的解釋。無法在Laravel中運行多個控制器測試
這裏的目標是測試我的登錄路線:http://my-development-server/login
。代碼應該像這樣工作:首先,檢查是否有人已經登錄 - 如果他們是,將它們重定向到儀表板(應用程序中的主頁面)。否則,呈現登錄頁面。非常直截了當。
這裏所涉及的路線:
Route::get('login', array(
'as' => 'login',
'uses' => 'MyApp\Controllers\[email protected]',
));
Route::get('/', array(
'as' => 'dashboard',
'uses' => 'MyApp\Controllers\[email protected]',
'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_login_alreadyLoggedIn
),第二次測試通過。如果我反向的兩種試驗方法,
test_login_notLoggedIn
通行證和test_login_alreadyLoggedIn
失敗(即在類穿過所述第一方法和第二失敗)的順序。
這在我看來就像某種配置問題 - 第一個測試(其中通過),東西弄亂了,它不能在第二次測試的請求後 - 但我不知所措。我已經多次閱讀了這本書,但是Google卻找不到任何我錯過的配置。
有什麼建議嗎?
感謝解決這個問題,僅僅用了20分鐘的調試同樣的問題!在routes.php中將require_once()改爲require()修復了測試問題,至今我還沒有注意到其他副作用。 – th3hamburgler
爲什麼它是一個問題,雖然?有人能解釋這背後的邏輯嗎? –