本文目录导读:

在 PHP 中进行模型测试,通常涉及单元测试和集成测试,以下是系统性的测试方法:
基础测试框架配置
使用 PHPUnit
composer require --dev phpunit/phpunit
phpunit.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true">
<testsuites>
<testsuite name="Model Test Suite">
<directory>tests/Models</directory>
</testsuite>
</testsuites>
</phpunit>
模型单元测试示例
Laravel 模型测试
<?php
namespace Tests\Unit\Models;
use Tests\TestCase;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
class UserModelTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function user_can_be_created()
{
$user = User::create([
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => bcrypt('secret123')
]);
$this->assertDatabaseHas('users', [
'email' => 'john@example.com'
]);
$this->assertInstanceOf(User::class, $user);
}
/** @test */
public function user_has_correct_fillable_fields()
{
$user = new User();
$this->assertEquals([
'name',
'email',
'password',
], $user->getFillable());
}
/** @test */
public function user_password_is_hashed()
{
$user = User::create([
'name' => 'Jane Doe',
'email' => 'jane@example.com',
'password' => 'plain-password'
]);
$this->assertNotEquals('plain-password', $user->password);
$this->assertTrue(password_verify('plain-password', $user->password));
}
}
纯 PHP 模型测试
<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Models\Product;
class ProductModelTest extends TestCase
{
/** @var Product */
private $product;
protected function setUp(): void
{
parent::setUp();
$this->product = new Product();
}
/** @test */
public function product_can_calculate_total_price()
{
$this->product->setPrice(100);
$this->product->setQuantity(3);
$this->assertEquals(300, $this->product->getTotalPrice());
}
/** @test */
public function product_name_is_required()
{
$this->expectException(\InvalidArgumentException::class);
$this->product->setName('');
}
}
关系测试
测试关联关系
<?php
namespace Tests\Feature\Models;
use Tests\TestCase;
use App\Models\Order;
use App\Models\User;
use App\Models\OrderItem;
use Illuminate\Foundation\Testing\RefreshDatabase;
class OrderModelTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function order_belongs_to_user()
{
$user = User::factory()->create();
$order = Order::factory()->create(['user_id' => $user->id]);
$this->assertInstanceOf(User::class, $order->user);
$this->assertEquals($user->id, $order->user->id);
}
/** @test */
public function order_has_many_order_items()
{
$order = Order::factory()->create();
OrderItem::factory()->count(3)->create(['order_id' => $order->id]);
$this->assertCount(3, $order->orderItems);
$this->assertInstanceOf(OrderItem::class, $order->orderItems->first());
}
/** @test */
public function order_can_calculate_total()
{
$order = Order::factory()->create();
OrderItem::factory()->create([
'order_id' => $order->id,
'price' => 100,
'quantity' => 2
]);
OrderItem::factory()->create([
'order_id' => $order->id,
'price' => 50,
'quantity' => 1
]);
$this->assertEquals(250, $order->calculateTotal());
}
}
使用工厂模式测试
定义 Model Factory
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'password' => bcrypt('password'),
];
}
public function admin()
{
return $this->state([
'is_admin' => true,
]);
}
}
使用工厂测试
/** @test */
public function admin_users_have_admin_privileges()
{
$admin = User::factory()->admin()->create();
$regularUser = User::factory()->create();
$this->assertTrue($admin->isAdmin());
$this->assertFalse($regularUser->isAdmin());
}
数据验证测试
/** @test */
public function model_validates_required_fields()
{
$order = new Order(['user_id' => null]);
$this->assertFalse($order->validate());
$this->assertArrayHasKey('user_id', $order->errors());
}
/** @test */
public function model_validates_email_format()
{
$user = new User(['email' => 'invalid-email']);
$this->assertFalse($user->validate());
$this->assertArrayHasKey('email', $user->errors());
}
模拟外部依赖
use Mockery;
/** @test */
public function model_calls_external_service()
{
$externalService = Mockery::mock(ExternalService::class);
$externalService->shouldReceive('sendEmail')
->once()
->andReturn(true);
$user = new User();
$user->setExternalService($externalService);
$result = $user->sendWelcomeEmail();
$this->assertTrue($result);
}
性能测试
/** @test */
public function model_query_uses_indexes()
{
$queries = 0;
DB::listen(function ($query) use (&$queries) {
$queries++;
// 检查查询是否使用索引
$this->assertStringNotContainsString('TABLE SCAN', $query->sql);
});
// 执行查询
User::where('email', 'john@example.com')->first();
$this->assertLessThan(5, $queries);
}
最佳实践建议
测试层级划分:
- 单元测试 - 单个模型方法
- 集成测试 - 模型与数据库交互
- 特征测试 - 完整业务流
关键要点:
/** @test */
public function test_model_scope()
{
// 测试查询作用域
$activeUsers = User::active()->get();
$this->assertNotEmpty($activeUsers);
}
/** @test */
public function test_model_accessors()
{
$user = User::factory()->create([
'first_name' => 'John',
'last_name' => 'Doe'
]);
$this->assertEquals('John Doe', $user->full_name);
}
/** @test */
public function test_model_mutators()
{
$user = new User();
$user->email = 'TEST@example.com';
$this->assertEquals('test@example.com', $user->email);
}
运行测试
# 运行所有测试 php artisan test # 运行特定测试文件 php artisan test --filter=UserModelTest # 运行测试并生成覆盖率 php vendor/bin/phpunit --coverage-html coverage/
这样系统化的测试方法能确保你的 PHP 模型逻辑正确、可靠且可维护。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播