Phpunit,模拟SoapClient存在问题(模拟魔术方法)

14

我正在尝试使用以下代码模拟SoapClient:

$soapClientMock = $this->getMockBuilder('SoapClient')
                ->disableOriginalConstructor()
                ->getMock();
$soapClientMock->method('getAuthenticateServiceSettings')
        ->willReturn(true);

由于Phpunit的mockbuilder找不到函数getAuthenticateServiceSettings,因此这无法工作。这是WSDL中指定的Soap函数。

但是,如果我扩展了SoapClient类和getAuthenticateServiceSettings方法,则可以工作。

问题在于我有数百个SOAP调用,每个调用都有自己的参数等,因此我不想模拟每个单独的SOAP函数,或者更多地重新创建整个WSDL文件...

是否有一种方法可以模拟"魔术"方法?

3个回答

27

5

我通常不直接使用 \SoapClient 类,而是使用一个使用 SoapClient 的 Client 类。例如:

class Client
{
    /**
     * @var SoapClient 
     */
    protected $soapClient;

    public function __construct(SoapClient $soapClient)
    {
        $this->soapClient = $soapClient;
    }

    public function getAuthenticateServiceSettings()
    {
        return $this->soapClient->getAuthenticateServiceSettings();
    }
}

这种方法比模拟SoapClient更容易模拟Client类。

6
当您需要为此Client类编写单元测试时会发生什么? - solarc

3

我无法在一个测试场景中使用 getMockFromWsdl,因此我模拟了后台调用的 __call 方法:

    $soapClient = $this->getMockBuilder(SoapClient::class)
        ->disableOriginalConstructor()
        ->getMock();
    $soapClient->expects($this->any())
        ->method('__call')
        ->willReturnCallback(function ($methodName) {
            if ('methodFoo' === $methodName) {
                return 'Foo';
            }
            if ('methodBar' === $methodName) {
                return 'Bar';
            }
            return null;
        });

顺便说一句,我先尝试使用__soapCall,因为__call已被弃用,但那并没有起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接