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

如何正确搭建贷款申请处理方法的测试场景?

解决测试中无法获取内部创建贷款记录ID的方案

核心问题

测试时,processLoanApplication方法内部才创建贷款记录,导致提前配置Http::fake时无法获取loan->id来填充API响应内容。以下是三种实用解决思路:


方案1:用闭包动态生成Fake响应

Http::fake支持通过闭包处理请求,在请求触发时(此时贷款记录已创建)动态获取loan_id并构造响应:

Http::fake([
    config('services.dummy.url').'/v3/transfers' => function ($request) use ($user, $loanProvider, $ref) {
        // 从用户关联中查询刚创建的最新贷款记录
        $loan = $user->loans()->latest()->first();
        
        return Http::response([
            'status' => 'success',
            'message' => 'test message',
            'data' => [
                'tx_ref' => $ref,
                'meta' => [
                    'user_id' => $user->id,
                    'loan_id' => $loan->id,
                    'loanProvider_id' => $loanProvider->id,
                    'transfer_description' => 'Loan Disbursement',
                ],
            ],
        ], 200);
    },
    config('services.dummy.url').'/v3/transactions/*/verify' => function ($request) use ($user) {
        $loan = $user->loans()->latest()->first();
        
        return Http::response([
            'status' => 'success',
            'message' => 'test message',
            'meta' => [
                'loan_id' => $loan->id,
            ],
        ], 200);
    },
]);

// 执行测试方法
$this->actingAs($user)->post('/process-loan', $formData);

这种方式利用闭包延迟执行特性,在实际API请求触发时,贷款记录已经存在,直接查询即可拿到正确的loan_id。


方案2:监听Loan模型的创建事件

通过Laravel模型事件捕获内部创建的贷款实例,再在Fake中使用该实例的ID:

use App\Models\Loan;

// 声明变量存储创建后的贷款实例
$createdLoan = null;

// 监听Loan模型的created事件
Loan::created(function ($loan) use (&$createdLoan) {
    $createdLoan = $loan;
});

// 配置Http Fake,使用捕获到的loan_id
Http::fake([
    config('services.dummy.url').'/v3/transfers' => function ($request) use ($user, $loanProvider, $ref, &$createdLoan) {
        return Http::response([
            'status' => 'success',
            'message' => 'test message',
            'data' => [
                'tx_ref' => $ref,
                'meta' => [
                    'user_id' => $user->id,
                    'loan_id' => $createdLoan->id,
                    'loanProvider_id' => $loanProvider->id,
                    'transfer_description' => 'Loan Disbursement',
                ],
            ],
        ], 200);
    },
    config('services.dummy.url').'/v3/transactions/'.$ref.'/verify' => function ($request) use (&$createdLoan) {
        return Http::response([
            'status' => 'success',
            'message' => 'test message',
            'meta' => [
                'loan_id' => $createdLoan->id,
            ],
        ], 200);
    },
]);

// 执行测试方法
$this->actingAs($user)->post('/process-loan', $formData);

// 后续断言
$this->assertNotNull($createdLoan);
Http::assertSentCount(2);

事件监听能精准捕获方法内部创建的贷款实例,确保Fake响应中的loan_id完全匹配实际数据。


方案3:先执行方法,再验证API请求

如果测试重点是验证API请求是否携带正确参数,而非依赖响应中的loan_id,可以先执行业务方法,再通过Http::assertSent验证请求:

// 先伪造通用成功响应,无需提前知道loan_id
Http::fake([
    config('services.dummy.url').'/*' => Http::response([
        'status' => 'success',
        'message' => 'test message',
        'data' => ['tx_ref' => $ref],
    ], 200),
]);

// 执行测试方法
$this->actingAs($user)->post('/process-loan', $formData);

// 获取实际创建的贷款记录
$loan = $user->loans()->latest()->first();

// 验证第一个API请求的参数正确性
Http::assertSent(function ($request) use ($loan, $user, $loanProvider) {
    return $request->url() === config('services.dummy.url').'/v3/transfers'
        && $request['meta']['loan_id'] === $loan->id
        && $request['meta']['user_id'] === $user->id
        && $request['meta']['loanProvider_id'] === $loanProvider->id;
});

// 验证第二个API请求的URL匹配
Http::assertSent(function ($request) use ($ref) {
    return str_ends_with($request->url(), "/v3/transactions/{$ref}/verify");
});

// 断言后续业务逻辑执行结果
$this->assertDatabaseHas('loans', [
    'id' => $loan->id,
    'status' => 'disbursed' // 假设放款后状态更新为已放款
]);

这种方式更关注请求的正确性,简化了Fake配置,适合验证流程完整性的测试场景。


额外建议:拆分测试关注点

将processLoanApplication的逻辑拆分为两个独立测试:

  1. 单独测试贷款创建:不调用API,仅验证表单数据是否正确存入数据库。
  2. 单独测试API调用与后续处理:手动创建Loan实例,传入disburseLoan方法,测试API调用和转账记录、贷款状态更新逻辑。

拆分后每个测试的职责更清晰,也避免了内部创建资源带来的测试耦合问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:43:18