Having a custom validation rule that uses the SoapClient
I now need to mock it in tests.
public function passes( $attribute, $value ): bool
{
$value = str_replace( [ '.', ' ' ], '', $value );
$country = strtoupper( substr( $value, 0, 2 ) );
$vatNumber = substr( $value, 2 );
$client = new SoapClient('https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', [ 'soap_version' => SOAP_1_1 ]);
$response = $client->checkVat( [ 'countryCode' => $country, 'vatNumber' => $vatNumber ] );
return $response->valid;
}
Used to use laminas-soap package but it doesn't support PHP8. With laminas-soap it was possible to do
$this->mock( Client::class, function( $mock )
{
$mock->shouldReceive( 'get' )->andReturn( new Response( true, 200 ) );
} );
But that doesn't work with SoapClient::class
.
Then tried from Phpunit, mocking SoapClient is problematic (mock magic methods) but also failed:
$soapClientMock = $this->getMockFromWsdl('soapApiDescription.wsdl');
$soapClientMock
->method('getAuthenticateServiceSettings')
->willReturn(true);
Tried from mock SoapClient response from local XML also failed:
$soapClient->expects($this->once())
->method('call')
->will(
$this->returnValue(true)
);
My question is how can I mock a soap response for a custom validation rule that uses SoapClient
?
My Answer:
One way to mock the SoapClient response for your custom validation rule is to create a wrapper class around the SoapClient and then mock this wrapper class in your tests. Here's an example of how you can do this:
First, create a wrapper class for the SoapClient:
php
class MySoapClient {
protected $client;
public function __construct($wsdl, $options) {
$this->client = new SoapClient($wsdl, $options);
}
public function checkVat($params) {
return $this->client->checkVat($params);
}
}
Then, in your custom validation rule, use this wrapper class instead of directly creating a SoapClient instance:
php
$client = new MySoapClient('https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', [ 'soap_version' => SOAP_1_1 ]);
$response = $client->checkVat([ 'countryCode' => $country, 'vatNumber' => $vatNumber ]);
Now, in your test, you can mock the MySoapClient class and define the behavior of the checkVat method:
php
$mockClient = $this->getMockBuilder(MySoapClient::class)
->disableOriginalConstructor()
->getMock();
$mockClient->expects($this->once())
->method('checkVat')
->willReturn((object) ['valid' => true]);
// Inject the mock client into your custom validation rule
// and test the behavior
This way, you can mock the SoapClient response for your custom validation rule by mocking the wrapper class around the SoapClient.
Rate this post
5 of 5 based on 4341 votesComments