Как проверить/сравнить/сопоставить аргументы stdClass, которые будут переданы в SoapClient?

Мой фон Java. Я почему-то думал, что погрузиться в PHP будет весело.

У меня есть файл WSDL с несколькими определенными методами, которые мне нужно вызвать. Каждый метод обычно имеет один определенный запрос и один тип ответа. Все эти типы имеют один или два уровня глубины, без атрибутов — только элементы. Ничего фантастического. Почти все методы требуют некоторых общих аргументов, таких как «имя пользователя» и «пароль».

Я решил протестировать все это, и поэтому я создал косвенность, которая обрабатывает передачу стандартных аргументов. Производственный код выглядит примерно так:

class PaymentManager implements IPaymentManager {

  public function __construct($soapClient, $username, $password, ...) {
    $this->soapClient = $soapClient; 
    $this->username = $username;
    ...
  }

  public function chargeCustomer($price, $customerId) {
    // prepare message
    $message = new stdClass();
    $message->ChargeMethodRequest = new stdClass();
    $message->ChargeMethodRequest->Username   = $this->username;
    $message->ChargeMethodRequest->Password   = $this->password;
    $message->ChargeMethodRequest->Price      = $price;
    $message->ChargeMethodRequest->CustomerID = $customerId;

    // make the actual call
    $result = $this->soapClient->chargeMethod($message->ChargeMethodRequest);

    // verify successful result
    if ($result->ChargeMethodResponse->Result === "SUCCESS") {
      throw new Exception("whopsie");
    }
  }

Теперь хитрость заключается в том, чтобы написать модульный тест для этого без необходимости использования реального экземпляра SoapClient. Я начал с SoapUI и сгенерировал примеры сообщений, но в файле PHP в виде статических строк, на которые я могу ссылаться из модульного теста. Итак, я представляю что-то вроде этого:

class WebServiceClientTest extends DrupalUnitTestCase /* yup, sad and true */ {

  public function test_charge_method_happy_path() {
    $soapClientMock = new SoapClientMock();
    $testee = new WebServiceClient($soapClientMock, $un, $pw, ...); 

    // arrange
    $successResponse = parseToStdClass(WebServiceClientMessages::RESPONSE_OK);
    $expectedMessage = parseToStdClass(WebServiceClientMessages::REQUEST_EXAMPLE_1);
    given($soapClientMock->chargeMethod($expectedMessage))->willReturn($successResponse);

    // act
    $testee->chargeCustomer("10.00", "customerId123");

    // assert
    verify($soapClientMock).chargeMethod($expectedMessage);
  }
}

Первая попытка, Phockito: не удалась, так как SoapClient является «родным» классом, и его нельзя использовать с Reflection* в PHP.

В противном случае я написал класс SoapClientMock, в котором я хочу заглушить вызовы методов, а также проверить взаимодействие. Это не имеет большого значения, но проблема заключается в сопоставлении аргументов.

Как я могу взять примеры сообщений (строки XML), проанализировать их во что-то, что я могу сравнить с объектами stdClass, которые нужны SoapClient для правильной привязки материала? Насколько я понимаю, сравнение объектов жестко запрограммировано и проверяет, относятся ли два объекта к одному классу.

SimpleXMLElement был моей первой надеждой, но его не очень легко сравнивать с объектом stdClass, главным образом из-за того, как SimpleXMLElement хочет использовать пространства имен повсюду.

Сериализация не работает, поскольку объекты SimpleXMLElement являются «собственными» классами.

Кто-то предложил сделать json_decode(json_encode($object)), а затем сравнить это, и это почти сработало, за исключением того, что SimpleXMLElement терпит неудачу, потому что нет способа получить дочерние узлы без указания пространства имен (и мне нужно использовать более одного), поэтому $expectedMessage не содержит все элементы.

В настоящее время я пишу свой собственный парсер «xml string to stdClass», используя SAX.

Но подождите - все, что я хотел, это убедиться, что PaymentManager правильно заполняет полезную нагрузку для chargeMethod - почему я закончил тем, что написал парсер SAX.


person Fredrik Wendt    schedule 11.12.2012    source источник


Ответы (1)


Я предполагаю, что один из вариантов - позволить SoapClientSpyMockFakeSomething extends SoapClient и переопределить метод __doRequest и использовать строку XML, которую вы там получите...

person Fredrik Wendt    schedule 11.12.2012