我正在尝试在TDD之后启动一个新的Laravel应用程序
我的第一步是检查主URL上是否已调用/ login控制器。
尽管有几个教程,我无法让测试工作,但我根本无法看到我做错了什么。
我的设置是: 作曲家安装laravel 作曲家安装phpunit
这是我的路线:
<?php
Route::get('/login', 'AuthenticationController@login');
我的控制员:
<?php
class AuthenticationController extends BaseController {
public function login () {
return View::make('authentication.login');
}
}
我的测试:
<?php
class AuthenticationTest extends TestCase {
public function testSomeTest () {
$response = $this->action('GET', 'AuthenticationController@login');
$view = $response->original;
$this->assertEquals('authentication.login', $view['name']);
}
}
我得到的错误是
ErrorException: Undefined index: name
代码作为Laravel网站的副本(几乎完全相同),但它没有运行。
谁能看到我做错了什么?
它声称$ view没有索引名称,但这不能正确,因为它是laravel网站上的示例,加上视图正在使用其名称呈现(它也在前端正确显示)
EDIT ::
因此,从评论中可以看出,laravel单元测试部分不清楚,$ view ['name']正在检查名为$ name的变量。如果是这种情况,您如何测试使用的控制器/路由,IE。路由('X')
使用了什么控制器名称/操作名称答案 0 :(得分:20)
好的,正如评论中已经解释的那样,让我们先退一步思考一下情景。
“我的第一步是检查主页面上是否已调用/ login控制器。”
这意味着:当用户点击归属路由时,您想要检查用户是否已登录。如果不是,则需要将其重定向到登录,可能还有一些flash消息。登录后,您需要将它们重定向回主页。如果登录失败,您希望将它们重定向回登录表单,也可以使用flash消息。
所以现在要测试几件事:家庭控制器和登录控制器。因此,遵循TDD精神,让我们首先创建测试。
注意:我将遵循phpspec使用的一些命名约定,但不要让这让您感到烦恼。
class HomeControllerTest extends TestCase
{
/**
* @test
*/
public function it_redirects_to_login_if_user_is_not_authenticated()
{
Auth::shouldReceive('check')->once()->andReturn(false);
$response = $this->call('GET', 'home');
// Now we have several ways to go about this, choose the
// one you're most comfortable with.
// Check that you're redirecting to a specific controller action
// with a flash message
$this->assertRedirectedToAction(
'AuthenticationController@login',
null,
['flash_message']
);
// Only check that you're redirecting to a specific URI
$this->assertRedirectedTo('login');
// Just check that you don't get a 200 OK response.
$this->assertFalse($response->isOk());
// Make sure you've been redirected.
$this->assertTrue($response->isRedirection());
}
/**
* @test
*/
public function it_returns_home_page_if_user_is_authenticated()
{
Auth::shouldReceive('check')->once()->andReturn(true);
$this->call('GET', 'home');
$this->assertResponseOk();
}
}
这就是Home控制器。在大多数情况下,您实际上并不关心重定向到哪里,因为这可能会随着时间而改变,您必须更改测试。所以你应该做的最少的事情就是检查你是否被重定向,如果你真的认为这对你的测试很重要,那么只检查更多细节。
我们来看看身份验证控制器:
class AuthenticationControllerTest extends TestCase
{
/**
* @test
*/
public function it_shows_the_login_form()
{
$response = $this->call('GET', 'login');
$this->assertTrue($response->isOk());
// Even though the two lines above may be enough,
// you could also check for something like this:
View::shouldReceive('make')->with('login');
}
/**
* @test
*/
public function it_redirects_back_to_form_if_login_fails()
{
$credentials = [
'email' => 'test@test.com',
'password' => 'secret',
];
Auth::shouldReceive('attempt')
->once()
->with($credentials)
->andReturn(false);
$this->call('POST', 'login', $credentials);
$this->assertRedirectedToAction(
'AuthenticationController@login',
null,
['flash_message']
);
}
/**
* @test
*/
public function it_redirects_to_home_page_after_user_logs_in()
{
$credentials = [
'email' => 'test@test.com',
'password' => 'secret',
];
Auth::shouldReceive('attempt')
->once()
->with($credentials)
->andReturn(true);
$this->call('POST', 'login', $credentials);
$this->assertRedirectedTo('home');
}
}
再次,总是想想你真正想要测试的东西。你真的需要知道在哪条路线上触发了哪个控制器动作?或者返回视图的名称是什么?实际上,您只需要确保控制器实际尝试来执行此操作。您传递一些数据,然后测试它是否按预期运行。
始终确保您没有尝试测试任何框架功能,例如,如果特定路由触发特定操作或者View正确加载。这已经过测试,因此您无需担心。专注于应用程序的功能而不是底层框架。