本文目录导读:

- 基础 PHPUnit 断言(通用)
- Laravel HTTP 测试断言(最常用,占80%)
- 数据库测试断言(重要)
- 集合与 Eloquent 断言
- 测试异常
- 格式化 / 验证响应
- 最推荐的组合用法(最佳实践)
- 💡 核心记忆技巧
在 Laravel 框架中,测试断言主要分为 PHPUnit 原生断言 和 Laravel 专用的测试响应断言。
以下是最常用且必须掌握的断言方法分类整理:
基础 PHPUnit 断言(通用)
这些是测试数据、逻辑最基础的判断。
| 断言方法 | 用途 | 示例 |
|---|---|---|
assertEquals($expected, $actual) |
判断两个值是否相等(松散比较,类型不严格,推荐用下面的) | $this->assertEquals(3, $result); |
assertSame($expected, $actual) |
判断两个值是否全等(严格类型+值) | $this->assertSame(10, $product->price); |
assertTrue($condition) |
断言条件为 true |
$this->assertTrue($user->isAdmin()); |
assertFalse($condition) |
断言条件为 false |
$this->assertFalse($user->isBanned()); |
assertNull($var) |
断言变量为 null |
$this->assertNull($user->deleted_at); |
assertNotNull($var) |
断言变量不为 null |
$this->assertNotNull($order->paid_at); |
assertCount($expected, $array) |
断言数组或集合的元素个数 | $this->assertCount(5, $users); |
assertEmpty($var) |
断言集合、数组、字符串为空 | $this->assertEmpty($cart->items); |
assertNotEmpty($var) |
断言不为空 | $this->assertNotEmpty($errors); |
assertInstanceOf($class, $obj) |
断言对象属于某个类(常用多态/服务容器) | $this->assertInstanceOf(ReportInterface::class, $service); |
assertArrayHasKey($key, $array) |
断言数组中存在指定键名 | $this->assertArrayHasKey('token', $data); |
assertContains($needle, $haystack) |
断言字符/数组包含指定项 | $this->assertContains('laravel', $str); |
assertDatabaseHas(常用独立) |
断言数据库中有对应记录 | (见下面数据库部分) |
Laravel HTTP 测试断言(最常用,占80%)
这些断言基于 $this->get()、$this->post()、$this->actingAs() 等功能。
状态码与视图
$response = $this->get('/login');
// 状态码
$response->assertStatus(200); // 默认成功
$response->assertOk(); // 等同于 assertStatus(200)
$response->assertRedirect('/home'); // 重定向
$response->assertNotFound(); // 404
$response->assertForbidden(); // 403
$response->assertUnauthorized(); // 401
$response->assertServerError(); // 500
// 视图相关
$response->assertViewIs('auth.login'); // 渲染的视图名称
$response->assertViewHas('user'); // 视图包含某个变量
$response->assertViewHas('users', $expectedUsers); // 视图变量值匹配
JSON / API 测试
$response = $this->postJson('/api/login', ['email' => 'a@b.c']);
$response->assertJson(['status' => 'success']); // 包含部分 JSON(推荐)
$response->assertExactJson(['status' => 'success', 'token' => 'abc']); // 完全一致
$response->assertJsonPath('data.user.id', 1); // 定位深层 JSON 路径
$response->assertJsonCount(5, 'data.items'); // JSON 数组元素个数
$response->assertJsonStructure(['data' => ['id', 'name']]); // 结构验证(无需值)
会话与 Cookies(Form 请求)
$response->assertSessionHas('key'); // Session 存在某 key
$response->assertSessionHas('errors'); // 验证失败时,Laravel 自动存 errors
$response->assertSessionHas('errors', 'email'); // errors 中包含 email 字段错误
$response->assertSessionHasNoErrors(); // 无任何验证错误
$response->assertSessionMissing('cart'); // Session 不存在某 key
// 或直接调用 session 助手:
$this->assertSessionHas('status', 'Profile updated!');
认证(Auth)
$user = User::factory()->create();
$this->actingAs($user); // 模拟登录
$response = $this->get('/dashboard');
$response->assertAuthenticated(); // 断言已认证
$this->assertAuthenticatedAs($user); // 断言指定用户
$response->assertGuest(); // 断言是游客(未登录)
数据库测试断言(重要)
测试与数据库交互时使用。
| 断言方法 | 用途 | 示例 |
|---|---|---|
assertDatabaseHas($table, $data) |
数据库表中存在匹配的记录 | $this->assertDatabaseHas('users', ['email' => 'a@b.c']); |
assertDatabaseMissing($table, $data) |
表中不存在匹配记录 | $this->assertDatabaseMissing('orders', ['status' => 'pending']); |
assertSoftDeleted($table, $data) |
确认数据是软删除状态 | $this->assertSoftDeleted('posts', ['id' => 1]); |
assertDatabaseCount($table, $count) |
表中记录总条数 | $this->assertDatabaseCount('users', 10); |
assertModelExists($model) |
模型在数据库中真实存在 | $this->assertModelExists($product); |
assertModelMissing($model) |
模型在数据库中不存在 | $this->assertModelMissing($product); |
集合与 Eloquent 断言
处理集合数据时的常用断言。
use Illuminate\Support\Collection;
$users = collect([...]);
$this->assertCount(3, $users);
$this->assertTrue($users->contains('name', 'John'));
$this->assertFalse($users->isEmpty());
测试异常
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('无效参数');
$this->expectExceptionCode(400);
// 或者直接用 try/catch
格式化 / 验证响应
// 断言响应头
$response->assertHeader('Content-Type', 'application/json');
// 断言响应内容(配合转义处理)
$response->assertSee('欢迎回来'); // 原始 HTML/JSON 字符串包含
$response->assertDontSee('错误信息');
$response->assertSeeInOrder(['第一', '第二']); // 按顺序出现
// 针对 API 响应格式:
$response->assertSuccessful(); // 2xx 状态码
最推荐的组合用法(最佳实践)
在真实项目中,通常在功能测试中组合使用:
public function test_user_can_login_successfully()
{
$user = User::factory()->create(['password' => bcrypt('secret')]);
// 1. 模拟提交请求
$response = $this->post('/login', [
'email' => $user->email,
'password' => 'secret',
]);
// 2. 断言:重定向到首页
$response->assertRedirect('/home');
// 3. 断言:数据库中用户被标记为已登录(通过会话)
$response->assertSessionHas('login_user_id', $user->id);
// 4. 断言:数据库有登录记录(若用登录日志表)
$this->assertDatabaseHas('login_logs', ['user_id' => $user->id]);
// 5. 断言:没有错误提示
$response->assertSessionHasNoErrors();
}
💡 核心记忆技巧
- 看状态码:
assertOk/assertRedirect/assertNotFound - :
assertSee/assertSessionHas/assertDatabaseHas - 看JSON结构:
assertJsonStructure/assertJsonPath - 看认证:
assertAuthenticated/assertGuest
注意:Laravel 10+ 中使用
assertSessionHas不再直接断言errors对象,而是用assertSessionHasErrors()方法简化掉,记得优先使用assertSessionHasNoErrors()来确保表单校验通过。
如果你在测试过程中遇到“断言失败”但无法定位问题,可以先用 $response->dump() 或 dd($response->json()) 在测试代码里打印响应内容,快速排查。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播