【问题标题】:How to mock an annotated AWS method in PHPUnit?如何在 PHPUnit 中模拟带注释的 AWS 方法?
【发布时间】:2019-11-27 18:44:48
【问题描述】:

我正在编写一个单元测试,我想检查方法 publish() 是否被调用了一次或多次。这是我整个测试班的一个 sn-p:

<?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'
        ]);
    }
}

但是当我运行上面的代码时,我得到了以下错误:

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

我猜这里的问题是AWS中的方法被定义为@method(见here):

* @method \Aws\Result publish(array $args = [])

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

更新

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

$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'
]);

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

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

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

【问题讨论】:

  • 该方法实际上并不存在。所有列出的方法都是通过魔术方法__call 实现的。您需要模拟魔术方法。
  • @CharlotteDunois 你能给我举个例子吗?我是 PHPUnit 的新手:|
  • 除了__call的函数签名是string $name, array $args之外,和其他任何方法一样,所以你只需要调整你的代码以反映你正在调用一个魔法方法。
  • @CharlotteDunois 你的建议有点用,但现在我遇到了一个不同的错误,我不确定我还缺少什么
  • 您忘记了方法的名称 (publish) 并且不要忘记 __call 接收的是 arguments 数组而不是普通参数。由于唯一的参数是一个数组,with 的第二个参数应该是一个数组数组(包装唯一参数的数组)。

标签: php aws-php-sdk phpunit


【解决方案1】:

从抛出的异常中,我们看到 __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]);

【讨论】:

  • 注意[$event]的包装数组不能是['Message' =&gt; 'foo', 'TopicArn' =&gt; 'bar']必须是[['Message' =&gt; 'foo', 'TopicArn' =&gt; 'bar']]
猜你喜欢
  • 2019-08-07
  • 2021-03-27
  • 1970-01-01
  • 2011-10-06
  • 2013-05-30
  • 2018-10-12
  • 2021-06-16
  • 2013-01-27
  • 2013-02-02
相关资源
最近更新 更多