单元测试
简介
Laravel 自建了单元测试。事实上,我们支持使用自带的 PHPUnit 进行测试,并且已经为你的应用程序配置好了 phpunit.xml
文件。除了 PHPUnit,Laravel 也使用了 Symfony HttpKernel,DomCrawler 和 BrowserKit 组件,允许你在测试中检查和操作视图以及模拟浏览器行为。
在 app/tests
目录下已经提供了一个测试示例文件。在安装了一个全新的 Laravel 应用程序之后,只需要简单的在命令行中执行 phpunit
, 即可运行你的测试。
定义 & 运行测试
要创建一个测试用例,只需要简单的在 app/tests
目录创建一个新的测试文件。测试类需要继承 TestCase
。然后你可以像使用 PHPUnit 一样来定义这些测试函数。
一个测试类示例
class FooTest extends TestCase {
public function testSomethingIsTrue()
{
$this->assertTrue(true);
}
}
你可以在终端执行 phpunit
命令来运行应用程序中的所有测试。
注意: 如果你定义了自己的
setUp
函数,请确保调用了parent::setUp
。
测试环境
在运行单元测试时,Laravel 将自动设置环境配置为 testing
。并且,Laravel 在测试环境中包含了 session
和 cache
配置文件。测试环境中,这两个驱动都被设置为空 array
,意味着在测试过程中,不会将 session 或者 cache 持久化。必要时,你也可以创建其他的测试环境。
测试中执行路由
在测试时可以很简单的使用 call
函数来执行一个路由:
测试中执行路由
$response = $this->call('GET', 'user/profile');
$response = $this->call($method, $uri, $parameters, $files, $server, $content);
你可以检查 Illuminate\Http\Response
对象:
$this->assertEquals('Hello World', $response->getContent());
你也可以在测试中执行控制器:
测试中执行控制器
$response = $this->action('GET', 'HomeController@index');
$response = $this->action('GET', 'UserController@profile', array('user' => 1));
getContent
函数将会返回和响应相同的字符串内容。如果路由返回 视图(View)
, 你可以使用 original
属性来访问:
$view = $response->original;
$this->assertEquals('John', $view['name']);
要执行一个 HTTPS 路由,可以使用 callSecure
函数:
$response = $this->callSecure('GET', 'foo/bar');
注意: 在测试环境中,路由过滤器将被禁用。如果需要启用它们, 请在你的测试中添加
Route::enableFilters()
。
DOM Crawler
你也可以执行一个路由并且接受一个 DOM Crawler 实例来检查内容:
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('h1:contains("Hello World!")'));
如需获取更多关于 DOM Crawler 的信息,请参见文档 official documentation。
模拟Facades
在测试时,你可能经常需要模拟执行一个 Laravel 静态 facade。例如,参考如下控制器的动作:
public function getIndex()
{
Event::fire('foo', array('name' => 'Dayle'));
return 'All done!';
}
我们可以通过在 facade 使用 shouldReceive
函数来模拟执行 Event
类, 它将返回一个 Mockery 模拟的实例。
模拟一个Facade
public function testGetIndex()
{
Event::shouldReceive('fire')->once()->with('foo', array('name' => 'Dayle'));
$this->call('GET', '/');
}
注意: 你不能模拟
Request
的 facade。替代的方式为,在运行你的测试时,将你预期的输入传给call
函数。
框架断言
Laravel 提供了一些 断言(assert)
函数来让测试更加容易:
断言响应为OK
public function testMethod()
{
$this->call('GET', '/');
$this->assertResponseOk();
}
断言响应状态码
$this->assertResponseStatus(403);
断言响应为重定向
$this->assertRedirectedTo('foo');
$this->assertRedirectedToRoute('route.name');
$this->assertRedirectedToAction('Controller@method');
断言视图含有的一些数据
public function testMethod()
{
$this->call('GET', '/');
$this->assertViewHas('name');
$this->assertViewHas('age', $value);
}
断言 Session 中含有的一些数据
public function testMethod()
{
$this->call('GET', '/');
$this->assertSessionHas('name');
$this->assertSessionHas('age', $value);
}
辅助函数
TestCase
类包含一些辅助函数来让应用程序测试更加容易。
你可以使用 be
函数来设置当前通过验证的用户:
设置当前通过验证的用户
$user = new User(array('name' => 'John'));
$this->be($user);
你可以在测试中使用 seed
函数来重新填充你的数据库:
测试中重新填充数据库
$this->seed();
$this->seed($connection);
如需获取更多关于创建数据填充的信息,请参见文档 迁移 & 数据填充。