Как тест удваивается, помогите мне протестировать устройство, которое взаимодействует с веб-сервисом SOAP через SoapClient
Недавно я начал свое путешествие по тестированию на php. Мне трудно разобраться в том, как тестировать внешние службы и как заглушка поможет мне убедиться, что тестируемый метод действительно ведет себя так, как обещает тест.
Следующий пример взят из кода, который я не могу понять, как тестировать. Я включил только рассматриваемую конструкцию и метод.
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;
}
}
В следующем тесте я попытался убедиться, что тест не использует SoapClient, ни SoapWrap, поскольку он использует SoapClient в качестве зависимого. Двойная обертка мыла вызвана вызовом ->getstations службы soap внутри getstations() в приведенном выше коде.
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);
}
}
Я не понимаю, как это гарантирует, что моя настоящая мыльная служба SoapWrap действительно возвращает массив, и как я должен это проверить. Насколько я понимаю, мой тест должен сначала завершиться неудачей, пока я не внедрю код, который позволит ему пройти. Но с этим тестом, который, скорее всего, будет явно неправильным, он всегда проходит. Что лишает меня любого значения, которое я могу понять из теста.
Я надеюсь, что вы можете помочь мне с некоторыми примерами того, как действительно протестировать такой метод.
2 answers
Я не на 100% понимаю пример в вашем вопросе, однако, если я правильно понимаю, вы хотите протестировать модуль SoapWrap
, и у него есть SoapClient
в качестве соавтора.
Теперь, когда вы создаете тест, если SoapWrap::getStations()
возвращает массив - что на самом деле всегда происходит - тест всегда будет пройден. Итак, для вашего первого вопроса о неудачном тесте, пока он не будет реализован (как в тестовой разработке (TDD): Тест завершается неудачно (Красный); Напишите как можно меньше кода, пока он не пройдет (Желтый (или: Зеленый)); Измените код (зеленый (или: Синий))), но вы сделали это неправильно. Вы должны были написать тест до написания кода, например, при первом вызове теста PHPUnit должен аварийно завершить работу с фатальной ошибкой, что класс SoapWrap
не найден и не может быть создан, потому что до сих пор он не был написан.
Так что удалите его сейчас и постарайтесь забыть код, который вы сделали до сих пор, повторите тест, чтобы увидеть, что он не удался, а затем напишите его заново.
Убедитесь, что вы провели модульное тестирование класса $StationFilter
до и это тоже.
Что касается второй части вашего вопроса о насмешках: Вы издеваетесь над сотрудниками, здесь, скорее всего, метод SoapClient::GetStations()
. Это избавит вас от необходимости фактически запускать удаленный запрос через SOAP. Это уже так просто. Вы издеваетесь над сотрудниками, чтобы протестировать устройство.
Возможно, это поможет вам опробовать созданный вами веб-сервис, вы можете попробовать смоделировать данные, передаваемые с помощью этого приложения. Проверьте здесь http://www.soapui.org/
Спасибо и с уважением, Джанитра Панджи