1

Mockery を使用して、例外がスローされたときにメソッドが別のメソッド内から呼び出されることをアサートしようとしています。例として:

public function testOtherMethodIsCalled() {

    $client = m::mock('Client');
    $client
        ->shouldReceive('getFoo')
        ->andThrow(new FooNotAvailableException);

    $controller = m::mock('Controller[otherMethod]');
    $controller
        ->shouldReceive('otherMethod')
        ->once();

    $controller->setClient($client);
    $controller->firstMethod();
}

明らかに名前は簡略化されていますが、それは私が持っているものと他のすべての点で同じです。コードでは、FooNotAvailableExceptionがキャッチされると、 への呼び出しを返しますotherMethod()

問題は、実行すると次のエラーが発生することです。

Mockery\CountValidator\Exception: Controller のメソッド otherMethod() は、正確に 1 回呼び出す必要がありますが、0 回呼び出す必要があります。

これは、元のモックされていないものが内部的にotherMethod()呼び出されているためです。テスト内から呼び出すとしたら、次のようになります。

$controller->otherMethod();

テストに合格します。

それはなぜですか? また、テストしたい内容のテストをどのように作成すればよいでしょうか?

4

1 に答える 1

0

完全なコード ソースがないとわかりにくいですが、これが起こっていることだと思います。

あなたのコード:

$client = m::mock('Client');
$client
    ->shouldReceive('getFoo')
    ->andThrow(new FooNotAvailableException);

ここまでは順調ですね。まだ問題ありません。

$controller = m::mock('Controller[otherMethod]');
$controller
    ->shouldReceive('otherMethod')
    ->once();

$controller->setClient($client);
$controller->firstMethod();

ここで、問題が発生します。テスト中のコードが別の URL にリダイレクトしていると仮定しています。その場合、別のコントローラーをインスタンス化します。インスタンス化したコントローラーは、「m::mock('Controller[otherMethod]')」によってインスタンス化されたコントローラーにはなりません。したがって、明らかに、モックされたインスタンスは「otherMethod」を受け取ることはありません。

テスト対象のコードが実際にどのように記述されているかによって、これをテストする適切な方法は、FooNotAvailableException を処理する関数から Redirect::to が呼び出されたことをアサートすることです。

于 2014-02-28T20:09:18.350 に答える