2

PHP でカスタム例外のキャプチャと処理をテストしようとしています。

追加のプロパティとメソッドを使用して、基本例外タイプを拡張しました。

スタブしているクラスの 1 つが例外をスローする可能性があります。その例外を正しくキャプチャして処理していることをテストできるようにしたいと考えています (この場合、呼び出しから返される応答オブジェクトを作成することを意味します)。

例えば

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_????" のインスタンスになります。カスタム例外を拡張しません。私の例外は、代わりに Mock_ErrorResponse の「$exception」プロパティに含まれています。

次のような恐ろしいことを強いられることなく、これを処理する方法はありますか?

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

if ($ex instanceof CustomExceptionType) {
...

私がテストしているクラスの中で?

4

2 に答える 2

3

まず第一に、代わりに:

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

try/catch 構造を使用する必要があります。

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

したがって、あなたの質問に答えると、基本的におそらくあなたは間違っているでしょう。スタブ化されたメソッドが例外をスローすると、メソッドで設定した例外を正確にスローする必要があるためです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、独自の実装例外に置き換えることができますが、これは引き続き機能するはずです。コードの何が問題なのかを理解するのにまだ問題がある場合は、より完全な例を投稿してください (例: スタブの作成方法)。たぶん、私はもっと助けることができます。

于 2013-02-26T10:55:57.033 に答える
1

現在、PHPUnit に組み込まれている @expectedException php-doc アノテーションを使用できます: 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()));
}
于 2015-11-30T01:06:42.227 に答える