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

Laravel 5.6中如何用PHPUnit和Mockery测试仓库模式update方法

为Laravel PackageController编写testUpdate()测试(PHPUnit + Mockery)

看起来你已经搞定了testIndex(),现在要写testUpdate()对吧?没问题,我来一步步教你怎么实现。我们的目标是验证PackageController的update方法是否正确调用了PackageInterface的updatePackage方法,并且返回预期的重定向响应。


步骤1:明确测试核心目标

我们只需要验证两件关键事:

  • PackageController@update 会正确调用 PackageInterface::updatePackage,传入符合要求的package_id参数
  • 方法执行完成后,会返回redirect()->back()的重定向响应

步骤2:编写完整的testUpdate()代码

直接上可运行的测试代码,我会逐行解释逻辑:

public function testUpdate()
{
    // 1. 准备测试用的包ID,选一个合理的数值即可
    $packageId = 1;

    // 2. 模拟一个更新后的Package模型实例(可选,但让测试逻辑更完整)
    // 注:Controller的update方法不会使用这个返回值,所以简单Mock即可
    $mockPackage = \Mockery::mock(\App\Models\Package::class);

    // 3. 设定Mock接口的预期行为:
    // 要求updatePackage方法被调用1次,参数必须是我们指定的$packageId,返回模拟的模型
    $this->mock
        ->shouldReceive('updatePackage')
        ->once()
        ->with($packageId)
        ->andReturn($mockPackage);

    // 4. 调用Controller的update方法
    $response = $this->target->update($packageId);

    // 5. 断言返回的是符合预期的重定向响应
    $this->assertInstanceOf(\Illuminate\Http\RedirectResponse::class, $response);
    $this->assertEquals(302, $response->getStatusCode()); // 验证重定向状态码
    $this->assertEquals(url()->previous(), $response->getTargetUrl()); // 验证重定向目标是上一页
}

步骤3:关键细节解释

  • Mock的自动验证:shouldReceive('updatePackage')->once() 会在测试结束时自动验证这个方法是否真的被调用了一次,如果调用次数不对或者没被调用,PHPUnit会直接抛出错误,不用额外写断言。
  • 为什么不需要模拟Request? 因为我们Mock的是PackageInterface,Controller调用的是Mock的updatePackage方法,而非实际PackageRepository的实现,所以Repository内部依赖的Request逻辑在这个测试里不会被触发。如果要验证PackageRepository的updatePackage逻辑,需要单独编写单元测试。

额外补充:测试PackageRepository的updatePackage方法(可选)

如果需要验证仓库层的业务逻辑是否正确,可以编写对应的单元测试,示例如下:

// Tests/Unit/PackageRepositoryTest.php
namespace Tests\Unit;

use Tests\TestCase;
use App\Repositories\PackageRepository;
use App\Models\Package;
use Illuminate\Http\Request;

class PackageRepositoryTest extends TestCase
{
    public function testUpdatePackage()
    {
        // 1. 创建测试用的Package实例并写入数据库
        $package = Package::factory()->create(['description' => '旧描述']);
        
        // 2. 模拟包含新描述的Request
        $request = Request::create('/packages/' . $package->id, 'PUT', [
            'description' => '更新后的新描述'
        ]);
        
        // 3. 实例化Repository,注入依赖
        $repository = new PackageRepository($request, new Package());
        
        // 4. 调用updatePackage方法
        $updatedPackage = $repository->updatePackage($package->id);
        
        // 5. 断言描述被正确更新
        $this->assertEquals('更新后的新描述', $updatedPackage->description);
        // 断言数据库中的数据也同步更新
        $this->assertDatabaseHas('packages', [
            'id' => $package->id,
            'description' => '更新后的新描述'
        ]);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:06:42