php: как смоделировать ответ SoapClient на __soapCall() в тесте PhpUnit

У меня есть служба RessortSoapService, которая использует ответ от вызова SOAP.

Я ввожу класс, который возвращает мне SoapClient:

public function __construct(ParameterBagInterface $params, SapSoapClientInterface $sapSoapClient)
{
    $this->params = $params;
    $this->soapClient = $sapSoapClient
        ->fetchWdslContent($this->params->get('sapwsdlstruktur'))
        ->getClient();
}

В классе SapSoapClient метод getClient() возвращает правильно инициализированный клиент:

public function getClient(): SoapClient
{
    $client = new SoapClient('data://text/plain;base64,' . base64_encode($this->wsdlContent), $this->options);

    return $client;
}

Теперь я хочу написать юнит-тест, который, конечно, НЕ должен вызывать сервер Soap, а просто подделывать ответ.

Что было сделано, так это:

class RessortSoapServiceTest extends TestCase
{
    public function setUp(): void
    {
        $this->prepareMocks();
        $this->ressortService = new RessortSoapService($this->params, $this->sapSoapClient);
    }

    private function prepareMocks()
    {
....

        $this->soapClient = $this->createMock(SoapClient::class);

        $this->soapClient
            ->method('__soapCall')
            ->willReturnCallback(
            '<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP:Header/>
   <SOAP:Body xmlns:urn="urn:sap-com:document:sap:rfc:functions">
      <nm:Z_STA_CUST_GET_RESSORTS.Response xmlns:nm="urn:sap-com:document:sap:rfc:functions" xmlns:prx="urn:sap.com:proxy:PV1:/1SAI/TASC3650D2D2360AAAFB21E:731">
         <ET_RESSORTS>
            <item>
               <GROUP_HIER>0000001</GROUP_HIER>
               <GROUP>0000001</GROUP>
               <IDENT>0000103</IDENT>
               <IS_INACTIVE>0</IS_INACTIVE>
            </item>
... some more XML

         </ET_RESSORTS>
         <ET_RETURN>
            <item>
               <TYPE>S</TYPE>
               <ID>ZSTA</ID>
               <NUMBER>401</NUMBER>
               <MESSAGE>Daten erfolgreich gelesen</MESSAGE>
            </item>
         </ET_RETURN>
      </nm:Z_STA_CUST_GET_RESSORTS.Response>
   </SOAP:Body>
</SOAP:Envelope>'
        );

        $this->sapSoapClient = $this->createMock(SapSoapClientInterface::class);

        $this->sapSoapClient
            ->method('getClient')
            ->willReturnCallback($this->soapClient);
    }

Поэтому я создал макет собственного SoapClient, которому я говорю, что он должен вернуть мне XML-строку, содержащую XML-ответ SOAP, вместо того, чтобы действительно связываться с SoapServer.

Когда я запускаю тест, __soapCall возвращает мне значение null, и поэтому мой тест не проходит.

Как я могу правильно издеваться над моим ответом __soapCall? Это мое первое использование Soap, поэтому, возможно, я упустил какую-то деталь или понимание?


person Calamity Jane    schedule 14.11.2019    source источник


Ответы (1)


Вы используете willReturnCallback. Это предполагает, что функция будет вызвана для фактического ответа. Поэтому он пытается найти функцию с именем всего вашего xml. Который, конечно же, не найдет. Если вместо этого вы используете willReturn, вы должны получить желаемый результат.

person Dirk Scholten    schedule 15.11.2019