Phpunit, mocking SoapClient is problematic (mock magic methods) Phpunit, mocking SoapClient is problematic (mock magic methods) php php

Phpunit, mocking SoapClient is problematic (mock magic methods)


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:

https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.stubbing-and-mocking-web-services.examples.GoogleTest.php


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.


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.