Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phpunit, mocking SoapClient is problematic (mock magic methods)

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?

like image 504
Patrik Grinsvall Avatar asked Aug 14 '14 07:08

Patrik Grinsvall


People also ask

What are mocks in PHPUnit?

The essence of a mock is that instead of a dependency object, you use a special object in which all the methods of the original class have been replaced. For such an object, you can configure the results returned by the methods and add checks for method calls. PHPUnit has a built-in mechanism for working with mocks.

Why should I use PHPUnit instead of getmock()?

Because PHPUnit offers better and simpler mocking syntax, less code, and some nice predefined methods. I usually create pure spies and stubs only when mocking them with getMock () would be too complicated. If your classes are so complex that getMock () can't handle them, then you have a problem with your production code--not with you tests.

What is mocking in Java?

The practice of replacing an object with a test double that verifies expectations, for instance asserting that a method has been called, is referred to as mocking. Lets assume we have SomeService to test.

What happened to createpartialmock() in PHPUnit?

createPartialMock () called with method (s) timerStopt that do not exist in PhpUnitMockDemo\AbstractCommand. This will not be allowed in future versions of PHPUnit. Unfortunately, this change was not reflected in the documentation — only setMethods () was still described there, and everything else was hidden in the depths of code and GitHub.


2 Answers

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

like image 116
user1777136 Avatar answered Oct 18 '22 02:10

user1777136


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.

like image 5
zuzuleinen Avatar answered Oct 18 '22 01:10

zuzuleinen