6

PHPにはいくつかのカスタム例外があります。

class MainException extends Exception {};
class ExceptionOne extends MainException {};
class ExceptionTwo extends MainException {};

そして、私はクラスで2つの簡単なメソッドでそれらを使用しています。

public function firstFunction($param) {
    if ($some_condition) {
        // do whatever
    } else {
        throw new ExceptionOne();
    }
}

public function secondFunction($param) {
    if ($some_condition) {
        // do whatever
    } else {
        throw new ExceptionTwo();
    }
}

私はまた、これに似た、両方の例外のPHPUnitテストを持っています:

public function testFirstException() {
    try {
        // anything
    } catch (Exception $e) {
        $this->assertType('ExceptionOne', $e);
        $this->assertType('MainException', $e);
    }
}
public function testSecondException() {
    try {
        // anything
    } catch (Exception $e) {
        $this->assertType('ExceptionTwo', $e);
        $this->assertType('MainException', $e);
    }
}

ブラウザーでクラスをテストし、意図的に関数を失敗させた場合(PHPUnitテストと同じもので)、必要に応じて表示さExceptionOneれ、ExceptionTwo発生します。ただし、PHPUnitでテストすると、常に失敗します。

1) testSecondException(SomeTest)
Failed asserting that <PHPUnit_Framework_ExpectationFailedException> is an instance of class "ExceptionTwo".
C:\test.php:67

67行目はそうですが
$this->assertType('ExceptionTwo', $e);
、何をしようとしてもここでは失敗します。私の状態はsecondFunction正しく機能していると確信しています。最初のテスト(testFirstException)は完全に機能し、2番目のテストのように失敗することはありません。
ここでPHPUnitテストを変更してはいけないことを付け加えたいと思います。

私はここで何が間違っているのですか?

4

3 に答える 3

7

try/catch内で別のエラーをマスクしているようです。tryブロック内にテストアサーションがあり、そのアサーションが失敗した場合、例外としてスローされます。setExpectedExceptiontry/catchブロックの代わりに使用してみてください。

public function testFirstException() {
    $this->setExpectedException('ExceptionOne');
    $fixture->firstFunction();
}

setExpectedException例外をスローする予定の行の直前に呼び出しを行う必要があります。

もう1つの方法は、@expectedExceptiondocblockアノテーションを使用することです。

/**
 * @expectedException ExceptionOne
 */
public function testFirstException() {
    $fixture->firstFunction();
}

try / catchアプローチを維持したい場合は、同じことが当てはまります。tryブロック内の唯一の行が、例外をスローする行であることを確認してください。

于 2012-11-02T15:38:21.210 に答える
7

あなたのコメントからcbuckleyの優れた答えまで、テストは次のように書かれているようです。

public function testFirstException() {
    try {
        // some code that is supposed to throw ExceptionOne
        $this->assertTrue(false, "Test failed");
    } catch (Exception $e) {
        $this->assertType('ExceptionOne', $e);
        $this->assertType('MainException', $e);
    }
}

assertTrue、テスト中に例外がスローされない場合にテストが失敗することを確認するために使用されます。ただし、失敗したアサーションが別の例外タイプをスローし、エラーメッセージが混乱するため、これは機能しません。

Failed asserting that <PHPUnit_Framework_ExpectationFailedException> 
is an instance of class "ExceptionOne".

@expectedExceptionまたはを使用してこれを修正できますsetExpectedException。がスローされたときにテストに合格するだけでなく、ExceptionOneスローされなかった場合やその他の例外タイプがスローされた場合にも失敗します。

/**
 * @expectedException ExceptionOne
 */
public function testFirstException() {
    // some code that is supposed to throw ExceptionOne
}

例外がスローされない場合、エラーメッセージは次のようになります。

Failed asserting that exception of type "ExceptionOne" is thrown.

異なるタイプの例外がスローされると、次のように表示されます。

Failed asserting that exception of type "Exception" matches
expected exception "RuntimeException".

例外をテストするこの方法は

  • 書きやすい、
  • 読みやすい、
  • テストが失敗したときのデバッグが簡単になります。
  • そして正しい。
于 2012-11-02T16:23:47.253 に答える
0

Try {}phpユニットを使用すると、応答を改ざんしているメソッドのいずれかに関する例外を生成する必要があります。

public function testFirstFunction() {
....
$this->methodOnGenerateExeption(Argumen::Any())->willReturn()->willThrow(\Exception::class);
$this->setExpectedException(\Exception::class);

  $this->classMockToTest->firstFunction($parameters)
}
于 2019-11-05T20:47:53.903 に答える