Phpunit - насмешливый SoapFault-> getMessage () - PullRequest
1 голос
/ 24 ноября 2011

Я подключаюсь к стороннему сервису с использованием SOAP. Этот сервис будет возвращать SoapFaults несколько раз. Поскольку это ожидается, я хочу проверить это, высмеивая SoapFaults. Существует пять стандартных SoapFaults, которые он вернет.

Вот начало настоящего SoapFault:

object(SoapFault)#7 (11) {
  ["message":protected]=>
  string(19) "{ 'INVALID_INPUT' }"

Я заинтересован в этом сообщении. В моем коде я использую $ e-> getMessage ().

catch (SoapFault $e)
{
    // Catch any Soap faults and convert to an error message
    switch ($e->getMessage())
    {
        case "{ 'INVALID_INPUT' }":
            $this->addError(self::INVALID_INPUT);
            return FALSE;

но я не могу понять, как высмеивать ответ SoapClient. Похоже, объект SoapClient не принимает никаких входных данных для установки сообщения, а метод getMessage() является окончательным, поэтому я не могу его смутить.

Любые идеи будут оценены. Спасибо.

Ответы [ 3 ]

5 голосов
/ 24 ноября 2011

Не надо издеваться над SoapFault. Вы можете просто использовать реальное исключение (обычно исключения не проверяются для тестирования, так как они Value objects) и имитировать SoapClient, чтобы вызвать ваше подготовленное исключение.

Поступая таким образом, вы не можете имитировать getMessage, потому что вы строите SoapFault в своем тестовом примере, как показано ниже.

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

Пример теста:

<?php

class SoapFaultTest extends PHPUnit_Framework_TestCase {

    public function testSoapFault() {
        $soapFault = new SoapFault("test", "myMessage");
        $soapClient = $this->getMockBuilder('SoapClient')
            ->setMethods(array('methodOnService'))
            ->disableOriginalConstructor()
            ->getMock();

        $soapClient->expects($this->once())
            ->method('methodOnService')
            ->will($this->throwException($soapFault));

        $x = new Consumer();
        $this->assertSame(
            "InvalidInput",
            $x->doSoapStuff($soapClient)
        );  
    }   

}

class Consumer {

    public function doSoapStuff(SoapClient $soapClient) {
        try {
            $soapClient->methodOnService();
        } catch(Exception $e) {
            if($e->getMessage() == "myMessage") {
                return "InvalidInput";
            }   
        }   
    }   
}

Выходы:

 phpunit SoapFaultTest.php 
PHPUnit 3.6.3 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.75Mb

OK (1 test, 2 assertions)

Утверждение остается простым, но вы легко сможете адаптировать его к своему способу обработки ошибок

1 голос
/ 25 ноября 2011

Я хочу поблагодарить Хакре за его комментарий. Это именно то, что я хотел.

SoapFault расширяет Исключение, которое ожидает ввода ($ message, $ code, $ previous). Но SoapFault ожидает ($ faultcode, $ faultstring, $ faultactor, $ detail, $ faultname, $ headerfault). Это то, что бросило меня.

Строка $ faultstring сопоставляется с сообщением об исключении.

Итак, чтобы высмеять это, я сделал:

$mock_soap->expects($this->once())
                         ->method('checkVat')
                         ->will($this->throwException(new SoapFault('a', "Error Message")));

И в моем реальном коде $ e-> getMessage () теперь возвращает сообщение об ошибке

1 голос
/ 24 ноября 2011

Помимо того, что ответил edorian, не нужно проверять, что сторонний компонент работает так, как было объявлено.Не пишите тесты для компонентов, для которых вы не написали код (или для которых вы не можете писать код, если они сломаны, они сломаны, и вы потерялись).

Просто протестируйте это Ваш код работает как положено.Вы должны быть в состоянии смоделировать свой собственный код.

Пример: ваш код всегда будет ломаться, если код или данные о нем отсутствуют, например, файлы вашего приложения частично удаляются при определенных обстоятельствах.Вы пишете тесты для таких сценариев?Естественно, нет.

Однако вы можете написать себе комплект интеграции, который автоматически проверяет, предоставляют ли определенные удаленные зависимости ожидаемый интерфейс и ответы.Но я бы выделил этот набор отдельно от ваших тестовых наборов, которые охватывают вашу собственную кодовую базу.

Дополнительно вы можете создать свои собственные функции подтверждения , которые можно использовать в каждом тестовом примере, например, одну дляСообщение об исключении SoapClient.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...