John Davidson

php - Laravel how to mock SoapClient response for custom validation rule

0 comments
Message:


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 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us