You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel功能测试:如何复用中间件测试逻辑避免冗余?

用Trait复用中间件测试逻辑的实操方案

用Trait来复用这类重复的中间件测试逻辑完全可行,具体操作可以这么做:

第一步:把通用测试逻辑抽成Trait

创建一个Trait,把那些重复的测试方法(无API密钥、未登录、空请求体这类)和通用方法移进去。为了适配不同端点,咱们可以加个抽象方法让具体测试类提供目标端点URL,这样Trait就能通用了。

示例代码:

trait TestsApiMiddleware
{
    // 通用基础请求头,如果不同测试需要改,直接重写就行
    protected function getBaseHeaders()
    {
        return [
            'Content-Type' => 'application/json',
        ];
    }

    // 必须实现的抽象方法:返回当前测试的端点URL
    abstract protected function getTestEndpoint(): string;

    /**
     * @test
     */
    public function no_api_key_returns_404()
    {
        $response = $this->postJson($this->getTestEndpoint(), [], $this->getBaseHeaders());
        $response->assertStatus(404);
    }

    /**
     * @test
     */
    public function not_logged_in_returns_401()
    {
        $headers = array_merge($this->getBaseHeaders(), [
            'X-API-Key' => config('app.api_key'), // 带API密钥但不带登录凭证
        ]);
        $response = $this->postJson($this->getTestEndpoint(), [], $headers);
        $response->assertStatus(401);
    }

    /**
     * @test
     */
    public function empty_body_returns_422()
    {
        $headers = array_merge($this->getBaseHeaders(), [
            'X-API-Key' => config('app.api_key'),
            'Authorization' => 'Bearer ' . $this->getValidAuthToken(),
        ]);
        $response = $this->postJson($this->getTestEndpoint(), [], $headers);
        $response->assertStatus(422);
    }

    // 通用的获取有效登录凭证方法,需要改的话直接在测试类里重写
    protected function getValidAuthToken(): string
    {
        $user = \App\Models\User::factory()->create();
        return $user->createToken('test-token')->plainTextToken;
    }
}

第二步:在具体测试类里用Trait

比如你的CreateImageTest,只需要引入这个Trait,实现抽象方法指定端点,剩下的中间件测试就自动有了,还能继续写当前端点特有的测试:

class CreateImageTest extends TestCase
{
    use TestsApiMiddleware;

    // 告诉Trait当前测试的是哪个端点
    protected function getTestEndpoint(): string
    {
        return '/api/images';
    }

    // 如果这个测试需要特殊的请求头或凭证,直接重写Trait里的方法就行
    // protected function getBaseHeaders()
    // {
    //     return array_merge(parent::getBaseHeaders(), [
    //         'X-Custom-Header' => 'value',
    //     ]);
    // }

    // 写当前端点特有的测试逻辑
    /**
     * @test
     */
    public function valid_request_creates_image_successfully()
    {
        // 你的特有测试代码
    }
}

几个关键点

  • 抽象方法做适配:通过getTestEndpoint()让Trait能适配不同的API端点,不用改Trait代码就能复用。
  • 灵活重写:如果某个测试的请求头、凭证逻辑不一样,直接重写Trait里的对应方法就行,不影响其他测试。
  • 避免冲突:Trait里的测试方法名尽量明确,比如no_api_key_returns_404,别和具体测试类的方法重名。

这样所有带同类中间件的端点测试,都能直接复用这套逻辑,再也不用复制粘贴重复代码了。

内容的提问来源于stack exchange,提问作者Melly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:16:42