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

如何Mock并测试服务中指定方法调用,忽略其他调用

Laravel Mock静态日志类:验证指定调用并忽略其他调用

现有代码

日志类 LogHelper

class LogHelper
{
    public static function log(string $type, string $message, array $context = []): void
    {
        Log::channel('test')->{$type}($message, $context);
    }
}

服务中的调用示例

$test->log('notice', 'test1234', ['1111' => '2222']);
$test->log('notice', 'test5678', ['3333' => '4444']);

需求

Mock LogHelper类,验证程序是否执行了指定调用:

$test->log('notice', 'test1234', ['1111' => '2222']);

同时忽略该方法的其他所有调用(比如上述示例中的第二条调用)。

当前尝试的问题

以下代码仅在仅存在指定调用时有效,一旦有其他log调用,测试会直接失败:

$this->mock(
    LogHelper::class,
    function (MockInterface $mock)  {
        $mock
            ->shouldReceive('log')
            ->withArgs(function ($type, $name, $context) {
                $this->assertSame('notice', $type);
                $this->assertSame('test1234', $name);
                $this->assertSame(['1111' => '2222'], $context);
                return true;
            });
    }
);

验收标准

测试通过(断言为true)的场景

  1. 包含指定调用和两个无关调用:
$test->log('notice', 'test', ['test' => 'test']);
$test->log('notice', 'test1234', ['1111' => '2222']);
$test->log('notice', 'test5678', ['3333' => '4444']);
  1. 包含指定调用和一个无关调用:
$test->log('notice', 'test1234', ['1111' => '2222']);
$test->log('notice', 'test5678', ['3333' => '4444']);
  1. 包含指定调用和另一个无关调用:
$test->log('notice', 'test', ['test' => 'test']);
$test->log('notice', 'test1234', ['1111' => '2222']);
  1. 仅包含指定调用:
$test->log('notice', 'test1234', ['1111' => '2222']);

测试失败(断言为false)的场景

  • 程序从未执行过指定的log('notice', 'test1234', ['1111' => '2222'])调用

解决方案

修改Mock逻辑,先断言指定调用至少执行一次,再允许其他任意log调用无限制执行:

$this->mock(LogHelper::class, function (MockInterface $mock) {
    // 验证指定的log调用至少执行一次
    $mock->shouldReceive('log')
         ->with('notice', 'test1234', ['1111' => '2222'])
         ->atLeast()->once();

    // 允许所有其他log调用,不进行断言
    $mock->shouldReceive('log')
         ->withAnyArgs()
         ->andReturn();
});

方案说明

  • ->with('notice', 'test1234', ['1111' => '2222']):精准匹配需要验证的调用参数
  • ->atLeast()->once():确保指定调用至少执行一次,覆盖所有测试通过场景
  • ->withAnyArgs():匹配所有其他log调用,andReturn()让这些调用无副作用执行,不会触发断言失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:22:13