I recently started my journey on testing in php. I am having a hard time getting my head around how to test external services and how a stub will help me assure that the method being testing really behaves as the test promises.
Following example is as taken from the code im unable to understand how to test. I have only included the construct and method in question.
class SoapWrap {
const WDSL_URL = 'http://traindata.dsb.dk/stationdeparture/Service.asmx?WSDL';
/**
* The WDSL/SOAP Client
* @access private
* @var \SoapClient $Client
*/
private $Client; // SOAP client.
/**
* Sets up \SoapClient connection.
* @throws \SoapFault upon SOAP/WDSL error.
*/
public function __construct( \SoapClient $SoapClient )
{
try
{
$this->Client = $SoapClient;
}
catch( \SoapFault $SoapFault )
{
throw $SoapFault;
}
}
/**
* Gets all stations and filters if a filter is passed.
*
* As DSB SOAP service only allows to get all stations
* a filter can be used narrow down the results.
* @param \DSBPHP\Filters\BaseFilter $StationFilte
* @return Array with station value objects.
*/
public function getStations( \DSBPHP\Filters\FilterInterface $StationFilter = null )
{
// DSB soap service inforces only method for getting all stations...
$stations = $this->Client->GetStations()->GetStationsResult->Station;
if($StationFilter !== null)
return $StationFilter->run($stations);
// return all trains
return $stations;
}
}
In the following in test, i have tried to insure that the test do not actully use the SoapClient nor the SoapWrap as it uses the SoapClient as dependecy. The SoapWrap double is because of the ->GetStations call on the soap service inside the getstations() in the code above.
class SoapWrapTest extends PHPUnit_Framework_TestCase {
private $SoapWrap;
public function setUp()
{
$SoapClient = $this ->getMockBuilder('\SoapClient')
->setMethods(['__construct'])
->disableOriginalConstructor()
->getMock();
$this->SoapWrap = $this ->getMockBuilder('\DSBPHP\App\SoapWrap')
->setMethods(['__construct', 'getStations'])
->disableOriginalConstructor()
->setConstructorArgs([$SoapClient])
->getMock();
}
public function testGetStationsReturnsArray()
{
$this->SoapWrap ->expects($this->once())
->method('getStations')
->will($this->returnValue([]));
$stations = $this->SoapWrap->getStations();
$this->assertInternalType('array', $stations);
}
}
I do not understand how this insures that my real soap service SoapWrap actully returns an array, and how i should test this. As i understand it, my test should fail at first, until i implement the code that makes it pass. But with this test, which most be obviously wrong, it always passes. Which takes away any value that i can understand from the test.
I hope you can help me with some examples of how to really test such method.