我试图用以下代码模拟SoapClient:
$soapClientMock = $this->getMockBuilder('SoapClient')
->disableOriginalConstructor()
->getMock();
$soapClientMock->method('getAuthenticateServiceSettings')
->willReturn(true);
这将不起作用,因为Phpunit mockbuilder没有找到getauthenticateservicessettings函数。这是WSDL中指定的Soap函数。
但是,如果我扩展SoapClient类和getauthenticateservicessettings方法,它确实可以工作。
问题是我有100个SOAP调用,都有自己的参数等,所以我不想模拟每一个SOAP函数,或多或少地重新创建整个WSDL文件…
是否有一种方法来模拟"魔法"方法?
PHPUnit允许您基于wsdl文件存根web服务。
$soapClientMock = $this->getMockFromWsdl('soapApiDescription.wsdl');
$soapClientMock
->method('getAuthenticateServiceSettings')
->willReturn(true);
请看下面的例子:
https://phpunit.de/manual/current/en/test-doubles.html test-doubles.stubbing-and-mocking-web-services.examples.GoogleTest.php
我通常不直接使用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类。
我不能在测试场景中使用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
被弃用,但没有工作。