如何在 PHPUnit 中模拟带注释的 AWS 方法?

Rey*_*rPM 5 php phpunit aws-php-sdk

我正在编写一个单元测试,我想检查该方法是否publish()被调用一次或多次。这是我整个测试课的一个片段:

<?php

namespace App\Tests\Unit;

use Aws\Sns\SnsClient;
use Exception;
use PHPUnit\Framework\TestCase;

class MyClassTest extends TestCase
{
    /** @var SnsClient */
    private $snsClient;

    public function setUp(): void
    {
        $this->snsClient = $this->getMockBuilder(SnsClient::class)->disableOriginalConstructor()->getMock();
    }

    /**
     * @throws Exception
     */
    public function testNoCaseIdentifierSns()
    {
        $this->snsClient->expects($this->once())->method('publish')->with([
            [
                'doc_id' => 1,
                'bucket' => 'some_bucket',
                'key'    => 'test.tiff/0.png'
            ],
            'topic_arn'
        ]);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行上面的代码时,出现以下错误:

尝试配置方法“publish”,但无法配置,因为它不存在、尚未指定、是最终的或静态的

我想这里的问题是AWS中的方法定义为@method(参见此处):

* @method \Aws\Result publish(array $args = [])
Run Code Online (Sandbox Code Playgroud)

可以模拟该方法吗?我在这里缺少什么?

更新

在遵循评论建议后,我将代码转换为以下内容:

$this->snsClient->expects($this->once())->method('__call')->with([
    'Message'  => json_encode([
        'doc_id' => 1,
        'bucket' => 'some_bucket',
        'key'    => 'test.tiff/0.png'
    ]),
    'TopicArn' => 'topic-arn'
]);
Run Code Online (Sandbox Code Playgroud)

但现在我收到了另一个错误:

调用 1 次时,方法名称等于“__call”的预期失败 调用 Aws\AwsClient::__call('publish', Array (...)) 的参数 0 与预期值不匹配。“发布”与预期类型“数组”不匹配。

为什么?publish()方法签名是一个数组args

Ant*_*ant 6

从抛出的异常中,我们看到 __call 函数是使用目标函数的名称(即“publish”)和包含所有参数的数组来调用的。因此,以下是更新模拟设置的方法:

$event = [
    'Message'  => json_encode([
        'doc_id' => 1,
        'bucket' => 'some_bucket',
        'key'    => 'test.tiff/0.png'
    ]),
    'TopicArn' => 'topic-arn'
];
$this->snsClient
    ->expects($this->once())
    ->method('__call')
    ->with('publish', [$event]);

Run Code Online (Sandbox Code Playgroud)