2013-02-25 2 views
2

Я пытаюсь проверить захват и обработку настраиваемого исключения в PHP.PHPUnit - сбрасывание, захват и обработка пользовательских исключений

Я расширил базовый тип исключения с некоторыми дополнительными свойствами и методами.

Один из классов, с которым я сталкиваюсь, может генерировать исключение, я хочу иметь возможность проверить, что я правильно фиксирую и обрабатываю это исключение (что в данном случае означает создание объекта ответа для возврата из вызова) ,

например.

try { 

    $objectBeingStubbed->doSomething(); 

} catch (\Exception $ex) { 

    if ($ex instanceof CustomExceptionType) { 

     $this->_errorResponse->error->message = $exception->getMessage(); 
     $this->_errorResponse->error->code = $exception->getCode(); 
     $this->_errorResponse->error->data = $exception->getData(); 

    } else { 

     throw $ex; 

    } 

} 

Я пытался имитировать исключение броска с:

$objectStub->expects($this->any()) 
      ->method('doSomething') 
      ->will($this->throwException(new CustomExceptionType())); 

Но когда исключение прибывает в классе я проверяю, что теперь экземпляр «Mock_ErrorResponse _ ????» который не расширяет мое пользовательское исключение. Мое исключение вместо этого содержится в свойстве «$ exception» в Mock_ErrorResponse.

Есть ли способ обработки этого, не будучи вынуждены делать что-то ужасное, как:

if ($ex instanceof PHPUnit_Framework_MockObject_Stub_Exception) { 
    $ex = $ex->exception; 
} 

if ($ex instanceof CustomExceptionType) { 
... 

Внутри класса я тестирование?

ответ

3

Прежде всего, вместо этого:

} catch (\Exception $ex) { 
    if ($ex instanceof CustomExceptionType) { 

вы должны использовать попытаться/структуру улова:

// (...) 
} catch (CustomExceptionType $e) { 
    // (...) 
} catch (\Exception $e) { 
    // (...) 
} 

Таким образом, отвечая на ваш вопрос, в принципе, возможно, вы делаете STH неправильно. Потому что, когда stubbed метод генерирует исключение, он должен точно указать исключение, которое вы установили с помощью метода throwException.

Я не знаю, как вы строите свою заглушку (возможно, там что-то сломано, возможно, пространства имен), но, пожалуйста, рассмотрите пример, ниже которого работает нормально.

class Unit 
{ 
    public function foo() 
    { 
     throw new \InvalidArgumentException(); 
    } 

    public function bar() 
    { 
     try { 
      $this->foo(); 
     } catch (\InvalidArgumentException $e) { 
      return true; 
     } catch (\Exception $e) { 
      return false; 
     } 

     return false; 
    } 
} 

class UnitTest extends \PHPUnit_Framework_TestCase 
{ 
    public function testBar() 
    { 
     $sut = $this->getMock('Unit', array('foo')); 
     $sut->expects($this->any()) 
      ->method('foo') 
      ->will($this->throwException(new \InvalidArgumentException())); 

     $this->assertTrue($sut->bar()); 
    } 
} 

Конечно, вы можете заменить InvalidArgumentException с вашим собственным исключением реализации, и это все еще должно работать. Если у вас все еще будут проблемы с выяснением того, что не так с вашим кодом, напишите более полный пример (например, как вы создаете свой заглушку). Может быть, тогда я могу больше помочь.

+0

спасибо за подсказку на другую структуру попробовать/поймать. Я пробовал это снова сегодня утром, и он работал, как ожидалось, не смог повторить проблему, которую я имел прошлой ночью. Я собираюсь положить его на глупую ошибку где-то с конца дня усталость. Спасибо еще раз за помощь! – Dan

1

В настоящее время вы можете использовать @expectedException PHP-Doc аннотацию встроенный в PHPUnit: https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.exceptions

/** 
* @expectedException InvalidArgumentException 
*/ 
public function testBar() 
{ 
    $sut = $this->getMock('Unit', array('foo')); 
    $sut->expects($this->any()) 
     ->method('foo') 
     ->will($this->throwException(new \InvalidArgumentException())); 
} 
Смежные вопросы