Laravel HTTP测试请求伪造详解
在Laravel中,HTTP测试请求伪造主要涉及如何模拟不同的HTTP请求方法和请求数据,以下是详细的实现方法:

基础请求方法伪造
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class HttpRequestTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function test_basic_http_requests()
{
// GET请求
$response = $this->get('/api/users');
// POST请求
$response = $this->post('/api/users', [
'name' => 'John Doe',
'email' => 'john@example.com'
]);
// PUT请求
$response = $this->put('/api/users/1', [
'name' => 'Jane Doe'
]);
// PATCH请求
$response = $this->patch('/api/users/1', [
'email' => 'jane@example.com'
]);
// DELETE请求
$response = $this->delete('/api/users/1');
// 断言状态码
$response->assertStatus(200);
}
}
高级请求伪造
<?php
namespace Tests\Feature;
use Tests\TestCase;
class AdvancedHttpRequestTest extends TestCase
{
/** @test */
public function test_advanced_request_methods()
{
// 带JSON头部的请求
$response = $this->withHeaders([
'accept' => 'application/json',
'X-CSRF-TOKEN' => csrf_token(),
])->post('/api/login', [
'email' => 'user@example.com',
'password' => 'secret'
]);
// 伪造Ajax请求
$response = $this->call(
'POST',
'/api/data',
[],
[],
[],
['HTTP_X-Requested-With' => 'XMLHttpRequest']
);
// 带会话的请求
$response = $this->withSession([
'user_id' => 1,
'role' => 'admin'
])->get('/admin/dashboard');
// 带查询参数的GET请求
$response = $this->get('/api/search', [
'q' => 'laravel',
'per_page' => 20
]);
}
/** @test */
public function test_request_with_files()
{
// 文件上传请求
$response = $this->post('/api/upload', [
'file' => UploadedFile::fake()->image('avatar.jpg', 200, 200)
]);
// 多个文件上传
$response = $this->post('/api/multiple-upload', [
'files' => [
UploadedFile::fake()->image('image1.jpg'),
UploadedFile::fake()->image('image2.jpg')
]
]);
}
}
路由固定的请求伪造
<?php
namespace Tests\Feature;
use Tests\TestCase;
class RouteSpecificTest extends TestCase
{
/** @test */
public function test_route_specific_requests()
{
// 使用路由名称生成请求URL
$response = $this->post(route('users.store'), [
'name' => 'John',
'email' => 'john@example.com'
]);
// 带路由参数的请求
$response = $this->withMiddleware('auth')
->get(route('users.show', ['id' => 1]));
// 带空间参数的POST请求
$response = $this->post(route('users.update', ['user' => 1]), [
'name' => 'Updated Name'
]);
// JSON API请求
$response = $this->postJson('/api/v1/users', [
'name' => 'Jane',
'email' => 'jane@example.com'
]);
}
}
模拟认证用户
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\User;
use Laravel\Sanctum\Sanctum;
class AuthenticatedRequestTest extends TestCase
{
/** @test */
public function test_authenticated_requests()
{
$user = User::factory()->create();
// 使用actingAs助手方法
$response = $this->actingAs($user)
->get('/dashboard');
// 指定守卫
$response = $this->actingAs($user, 'admin')
->get('/admin/dashboard');
// Sanctum API认证
Sanctum::actingAs($user, ['view-api']);
$response = $this->getJson('/api/users');
// 带Bearer Token的请求
$token = $user->createToken('api-token')->plainTextToken;
$response = $this->withToken($token)
->getJson('/api/user');
}
}
模拟请求头和IP地址
<?php
namespace Tests\Feature;
use Tests\TestCase;
class HeaderIpTest extends TestCase
{
/** @test */
public function test_custom_headers_and_ip()
{
// 自定义头部
$response = $this->withHeaders([
'Authorization' => 'Bearer token123',
'X-API-Key' => 'abcdef123456',
'User-Agent' => 'CustomAgent/1.0'
])->get('/api/data');
// 模拟IP地址
$response = $this->call(
'GET',
'/api/geo',
[],
[],
[],
[
'REMOTE_ADDR' => '192.168.1.100',
'HTTP_X_FORWARDED_FOR' => '203.0.113.1'
]
);
// 使用withServerVariables
$response = $this->withServerVariables([
'REMOTE_ADDR' => '10.0.0.1',
'HTTP_USER_AGENT' => 'TestBrowser/1.0'
])->post('/api/submit');
}
}
复杂业务场景测试
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Order;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
class ComplexScenarioTest extends TestCase
{
use WithFaker;
/** @test */
public function test_typical_api_workflow()
{
// 创建数据
$user = User::factory()->create();
$order = Order::factory()->create(['user_id' => $user->id]);
// 1. 登录获取Token
$loginResponse = $this->postJson('/api/login', [
'email' => $user->email,
'password' => 'password123'
]);
$token = $loginResponse->json('data.token');
// 2. 使用Token请求数据
$orderResponse = $this->withHeaders([
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json'
])->getJson("/api/orders/{$order->id}");
$orderResponse->assertOk()
->assertJsonStructure([
'data' => [
'id',
'total',
'status'
]
]);
// 3. 提交复杂请求数据
$createResponse = $this->postJson('/api/orders', [
'customer_name' => $this->faker->name(),
'items' => [
['product_id' => 1, 'quantity' => 2],
['product_id' => 2, 'quantity' => 1]
],
'shipping_address' => [
'street' => $this->faker->streetAddress(),
'city' => $this->faker->city(),
'zip' => $this->faker->postcode()
]
]);
$createResponse->assertStatus(201);
}
}
测试JSON和XML请求
<?php
namespace Tests\Feature;
use Tests\TestCase;
class JsonXmlTest extends TestCase
{
/** @test */
public function test_json_and_xml_requests()
{
// JSON请求
$jsonResponse = $this->postJson('/api/users', [
'name' => 'John',
'email' => 'john@example.com'
]);
$jsonResponse->assertJson([
'success' => true
]);
// XML请求(需要自定义)
$xmlResponse = $this->call(
'POST',
'/api/xml-handler',
[],
[],
[],
['CONTENT_TYPE' => 'application/xml'],
'<root><name>John</name></root>'
);
// 断言JSON结构
$this->postJson('/api/users')
->assertJsonStructure([
'data' => [
'*' => [
'id',
'name',
'email'
]
]
]);
// 断言部分JSON
$this->getJson('/api/users/1')
->assertJsonFragment([
'name' => 'John Doe'
]);
}
}
请求伪造的最佳实践
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class BestPracticesTest extends TestCase
{
use RefreshDatabase;
/**
* 使用辅助方法封装请求
*/
private function authenticateAndGetUser()
{
$user = \App\Models\User::factory()->create([
'email' => 'test@example.com',
'password' => bcrypt('password')
]);
$token = $user->createToken('test')->plainTextToken;
return [$user, $token];
}
/** @test */
public function test_best_practices()
{
// 1. 为测试创建数据工厂
$user = \App\Models\User::factory()->create();
$order = \App\Models\Order::factory()
->for($user)
->create();
// 2. 定义明确的测试意图
$this->withoutExceptionHandling(); // 调试时使用
// 3. 使用数据库事务
$response = $this->transact(function () {
return $this->post('/api/users', [
'name' => 'John',
'email' => 'john@example.com'
]);
});
// 4. 建立测试环境配置
$this->app['config']->set('api-timeout', 30);
// 5. 使用数据提供者进行多场景测试
$responses = collect([
['name' => 'John', 'email' => 'john@example.com'],
['name' => 'Jane', 'email' => 'jane@example.com']
])->map(function ($data) {
return $this->post('/api/users', $data);
});
$responses->each(function ($response) {
$response->assertStatus(201);
});
}
}
总结关键点:
- get()/post()/put()/patch()/delete() 是基本的请求方法
- postJson()/getJson() 用于JSON API请求
- actingAs() 模拟认证用户
- withHeaders() 设置请求头部
- withSession() 模拟会话数据
- call() 提供更底层的请求控制
- UploadedFile::fake() 模拟文件上传
- Sanctum::actingAs() 用于API认证测试
这些方法组合使用可以覆盖绝大多数HTTP测试场景。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播