PHP项目Laravel测试断言有哪些常用

wen PHP项目 3

本文目录导读:

PHP项目Laravel测试断言有哪些常用

  1. 基础 PHPUnit 断言(通用)
  2. Laravel HTTP 测试断言(最常用,占80%)
  3. 数据库测试断言(重要)
  4. 集合与 Eloquent 断言
  5. 测试异常
  6. 格式化 / 验证响应
  7. 最推荐的组合用法(最佳实践)
  8. 💡 核心记忆技巧

在 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()) 在测试代码里打印响应内容,快速排查。

抱歉,评论功能暂时关闭!