Reputation: 672
Im trying to mock SoapClient with the following code:
$soapClientMock = $this->getMockBuilder('SoapClient')
->disableOriginalConstructor()
->getMock();
$soapClientMock->method('getAuthenticateServiceSettings')
->willReturn(true);
This will not work since Phpunit mockbuilder does not find the function getAuthenticateServiceSettings. This is a Soap function specified in the WSDL.
However, if i extend the SoapClient class and the getAuthenticateServiceSettings method it does work.
The problem is i have 100s of SOAP calls, all with their own parameters etc. so i dont want to mock every single SOAP function and more or less recreate the whole WSDL file...
Is there a way to mock "magic" methods?
Upvotes: 14
Views: 11392
Reputation: 5738
I wasn't able to use getMockFromWsdl
for a test scenario, so I mocked the __call
method which is called in the background:
$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;
});
P.S. I tried using __soapCall
first since __call
is deprecated but that didn't work.
Upvotes: 3
Reputation: 1756
PHPUnit allows you to stub a web service based on a wsdl file.
$soapClientMock = $this->getMockFromWsdl('soapApiDescription.wsdl');
$soapClientMock
->method('getAuthenticateServiceSettings')
->willReturn(true);
See example here:
Upvotes: 28
Reputation: 2634
I usually don't work with the \SoapClient class directly, instead I use a Client class which uses the SoapClient. For example:
class Client
{
/**
* @var SoapClient
*/
protected $soapClient;
public function __construct(SoapClient $soapClient)
{
$this->soapClient = $soapClient;
}
public function getAuthenticateServiceSettings()
{
return $this->soapClient->getAuthenticateServiceSettings();
}
}
This way is easier to mock the Client class, than mocking the SoapClient.
Upvotes: 5