42

基本的に、killProgramというクラスのメソッドがあります。これは、hTTPリダイレクトを送信してからPHPを強制終了することを目的としています。

これをどのようにテストするのですか?phpunitを実行すると、そのテストでは何も返されず、完全に閉じます。

現在、killProgram関数に、処理されるべきではない例外をスローさせることを検討しています。これにより、例外がスローされたことを表明できます。

もっと良い方法はありますか?

4

6 に答える 6

28

これは明らかに古い質問ですが、私の提案は、コードをdie()別のメソッドに移動して、それをモックできるようにすることです。

例として、これを持っている代わりに:

class SomeClass
{
    public function do()
    {
        exit(1);
        // or
        die('Message');
    }
}

これを行う:

class SomeClass
{
    public function do()
    {
        $this->terminate(123);
        // or
        $this->terminate('Message');
    }

    protected function terminate($code = 0)
    {
        exit($code);
    }

    // or 
    protected function terminate($message = '')
    {
        die($message);
    }
}

そうすれば、メソッドを簡単にモックできterminate、スクリプトをキャッチできずにスクリプトが終了することを心配する必要はありません。

テストは次のようになります。

class SomeClassTest extends \PHPUnit_Framework_TestCase
{

    /**
     * @expectedExceptionCode 123
     */
    public function testDoFail()
    {
        $mock = $this->getMock('SomeClass');
        $mock->expects($this->any())
             ->method('terminate')
             ->will($this->returnCallback(function($code) {
                 throw new \Exception($code);
             }));

        // run to fail
        $mock->do();
    }
}

私はコードをテストしていませんが、動作状態にかなり近いはずです。

于 2014-02-05T13:08:31.193 に答える
26

すべてのテストは同じPHPUnitプロセスによって実行されるため、PHPコードでexit / dieを使用すると、気付いたようにすべてが強制終了されます^^

ですから、別の解決策を見つける必要があります。そうです。死ぬ代わりに戻るようなものです。または例外をスローします(テストされたコードが予期された例外をスローしたかどうかをテストできます)

たぶん、PHPUnit 3.4とその--process-isolationスイッチ(オプションで個別のPHPプロセスを使用して各テストを実行するを参照)は役立つかもしれませんが(すべてが死ぬことはありません)、PHPUnitが取得しない場合は、テストの結果を取得できません。コントロールバック。

私はこの問題を数回経験しました; 死ぬ代わりに戻ることで解決しました。必要に応じて何度か戻って、コールスタックの「十分な高さ」に戻ることもできます^^
結局、アプリケーションに「死ぬ」ことはもうないと思います。 .. MVCについて考えるときは、おそらくもっと良いでしょう。

于 2009-08-28T15:50:22.777 に答える
14

テストするためだけにコードを変更する必要はありません。使用するだけです( PHPUnitと同じ作成者からset_exit_overload()提供されます)。test_helpers

于 2012-02-29T11:52:00.590 に答える
7

あなたはすでにこれに対する答えを受け入れており、それは古い質問だと思いますが、これは誰かにとって役立つかもしれないと思うので、ここに行きます:

を使用する代わりに、(または独自の例外クラス)をdie()使用することもできますthrow new RuntimeException()。これにより、プログラムの実行が停止し(方法は異なりますが)、PHPUnitを使用setExpectedException()してそれをキャッチします。その例外が発生したときにスクリプトでスクリプトを実行したい場合die()は、ユーザーのレベルで何も出力しないようにします。を見てくださいset_exception_handler()

具体的にはset_exception_handler()、テストで使用されないブートストラップファイルに-callを配置するシナリオを考えています。これにより、シナリオに関係なくハンドラーがそこで起動しないため、PHPUnitのネイティブ例外処理に干渉するものはありません。 。

于 2010-04-21T13:33:04.070 に答える
5

これは、テストに合格するためにいくつかのレガシーコードを取得してきた一連の問題に関連しています。だから私はこのようなテスト可能なクラスを思いついた...

class Testable {
   static function exitphp() {
      if (defined('UNIT_TESTING')) {
         throw new TestingPhpExitException();
      } else {
         exit();
      }
   }
}

ここで、exit()の呼び出しをTestable :: exitphp()に置き換えるだけです。

テスト中の場合は、UNIT_TESTINGを定義するだけですが、本番環境では定義しません。単純なモックのようです。

于 2013-12-12T21:11:30.593 に答える
0

環境変数の値に応じて、スクリプトを強制終了するか、例外をスローできます...

したがって、本番環境で強制終了するか、テスト環境で例外をスローします。

死ぬか終了するための呼び出しは、プロセス全体を強制終了します...

これはコメントのはずだったのですが、レピュテーションポイントのレベルでコメントすることはできません。

于 2019-08-07T07:31:21.300 に答える