Skip to content

测试

介绍

Laravel 是以单元测试为核心构建的。实际上,支持使用 PHPUnit 进行测试是开箱即用的,并且 phpunit.xml 文件已经为您的应用程序设置好了。

tests 目录中提供了一个示例测试文件。安装新的 Laravel 应用程序后,只需在命令行中运行 phpunit 即可运行您的测试。

定义和运行测试

要创建测试用例,只需在 tests 目录中创建一个新的测试文件。测试类应继承 TestCase。然后,您可以像使用 PHPUnit 时一样定义测试方法。

示例测试类

php
class FooTest extends TestCase {

	public function testSomethingIsTrue()
	{
		$this->assertTrue(true);
	}

}

您可以通过在终端中执行 phpunit 命令来运行应用程序的所有测试。

lightbulb

如果您定义了自己的 setUp 方法,请确保调用 parent::setUp

测试环境

运行单元测试时,Laravel 会自动将配置环境设置为 testing。此外,Laravel 在测试环境中包含了 sessioncache 的配置文件。在测试环境中,这两个驱动程序都设置为 array,这意味着在测试时不会持久化任何会话或缓存数据。您可以根据需要创建其他测试环境配置。

testing 环境变量可以在 phpunit.xml 文件中配置。

从测试中调用路由

从测试中调用路由

您可以使用 call 方法轻松调用测试中的路由:

php
$response = $this->call('GET', 'user/profile');

$response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content);

然后,您可以检查 Illuminate\Http\Response 对象:

php
$this->assertEquals('Hello World', $response->getContent());

从测试中调用控制器

您还可以从测试中调用控制器:

php
$response = $this->action('GET', 'HomeController@index');

$response = $this->action('GET', 'UserController@profile', ['user' => 1]);
lightbulb

使用 action 方法时,您不需要指定完整的控制器命名空间。只需指定类名中 App\Http\Controllers 命名空间之后的部分即可。

getContent 方法将返回响应的评估字符串内容。如果您的路由返回一个 View,您可以使用 original 属性访问它:

php
$view = $response->original;

$this->assertEquals('John', $view['name']);

要调用 HTTPS 路由,您可以使用 callSecure 方法:

php
$response = $this->callSecure('GET', 'foo/bar');

模拟 Facades

在测试时,您可能经常需要模拟对 Laravel 静态 facade 的调用。例如,考虑以下控制器操作:

php
public function getIndex()
{
	Event::fire('foo', ['name' => 'Dayle']);

	return 'All done!';
}

我们可以使用 facade 上的 shouldReceive 方法模拟对 Event 类的调用,该方法将返回一个 Mockery 模拟实例。

模拟 Facade

php
public function testGetIndex()
{
	Event::shouldReceive('fire')->once()->with('foo', ['name' => 'Dayle']);

	$this->call('GET', '/');
}
lightbulb

您不应模拟 Request facade。相反,在运行测试时将所需的输入传递给 call 方法。

框架断言

Laravel 附带了几个 assert 方法,以使测试更容易:

断言响应正常

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertResponseOk();
}

断言响应状态

php
$this->assertResponseStatus(403);

断言响应是重定向

php
$this->assertRedirectedTo('foo');

$this->assertRedirectedToRoute('route.name');

$this->assertRedirectedToAction('Controller@method');

断言视图有一些数据

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertViewHas('name');
	$this->assertViewHas('age', $value);
}

断言会话有一些数据

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertSessionHas('name');
	$this->assertSessionHas('age', $value);
}

断言会话有错误

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertSessionHasErrors();

	// 断言会话有给定键的错误...
	$this->assertSessionHasErrors('name');

	// 断言会话有多个键的错误...
	$this->assertSessionHasErrors(['name', 'age']);
}

断言旧输入有一些数据

php
public function testMethod()
{
	$this->call('GET', '/');

	$this->assertHasOldInput();
}

辅助方法

TestCase 类包含几个辅助方法,以使测试您的应用程序更容易。

从测试中设置和刷新会话

php
$this->session(['foo' => 'bar']);

$this->flushSession();

设置当前认证用户

您可以使用 be 方法设置当前认证用户:

php
$user = new User(['name' => 'John']);

$this->be($user);

从测试中重新播种数据库

您可以使用 seed 方法从测试中重新播种数据库:

php
$this->seed();

$this->seed('DatabaseSeeder');

有关创建种子的更多信息,请参阅文档中的 迁移和播种 部分。

刷新应用程序

如您所知,您可以从任何测试方法访问您的应用程序(服务容器)通过 $this->app。每个测试类都会刷新此服务容器实例。如果您希望手动强制应用程序为给定方法刷新,您可以从测试方法中使用 refreshApplication 方法。这将重置自测试用例开始运行以来放置在 IoC 容器中的任何额外绑定,例如模拟。