2012-02-26 18 views
4

自分自身でカスタムPHPUnit制約を作成し、それを素晴らしいassert...関数に接続しました。しかし、テストランナーはない、私がこれまでに制約をデバッグしてきましたカスタムPHPUnit制約が機能しなくなりました

/** 
* abstract, base test-case class. 
*/ 
abstract class TestCase extends \PHPUnit_Framework_TestCase 
{ 
    /** 
    * assert lint of a php file 
    */ 
    protected function assertLint($filename, $message = '') { 
     self::assertThat($filename, new ConstraintLint, $message); 
    } 
    /** 
    * assert the last error 
    */ 
    protected function assertLastError($error, $file, $message = '') { 
     self::assertThat($file, new ConstraintLastError($error), $message); 
    } 
    /** 
    * assert XML DTD validity 
    */ 
    protected function assertXmlStringValidatesDtdUri($xml, $dtd, $message = '') { 
     self::assertThat($dtd, new ConstraintXmlStringValidatesDtdUri($xml), $message); 
    } 

    ... 

と私はevaluateメソッドが呼び出されることを確認し、FALSEを返します:私は私のベースTestCaseにそれを滑ら

は、それはassertLastError機能です私に失敗を報告しないでください。

制約:

/** 
* ConstraintLastError 
* 
* For asserting the last error message in a file. 
* 
* To test trigger_error(). 
* 
* Example: 
* 
* $this->assertLastError('Error Message', 'basenameOfFile.php'); 
* 
*/ 
class ConstraintLastError extends \PHPUnit_Framework_Constraint { 
    private $file; 
    private $error; 
    public function __construct($error) { 
     $this->error = $error; 
    } 
    /** 
    * Evaluates the constraint for parameter $file. Returns TRUE if the 
    * constraint is met, FALSE otherwise. 
    * 
    * @param string $file Value or object to evaluate. 
    * @return bool 
    */ 
    public function evaluate($file) 
    { 
     $this->file = $file; 
     $error = $this->error; 
     $lastError = error_get_last(); 
     if (NULL === $lastError) 
      return false; 

     $last_message = $lastError['message']; 
     $last_file = $lastError['file']; 


     $result = ($error == $last_message && basename($file) == basename($last_file)); 

     var_dump($result, $error, $last_message, $file, $last_file); 

     return $result; 
    } 

    /** 
    * @param mixed $other 
    * @param string $description 
    * @param boolean $not 
    */ 
    protected function customFailureDescription($other, $description, $not) 
    { 
     return sprintf('Failed asserting that the last error %s', basename($other), $not ? '' : 'no ', implode("\n - ", $this->lines)); 
    } 


    /** 
    * Returns a string representation of the constraint. 
    * 
    * @return string 
    */ 
    public function toString() 
    { 
     return sprintf('was %s in file %s.', $this->error, $this->file); 
    } 
} 

これは動作を停止し、なぜ私は見当がつかないが、テストケースはちょうど私が出力税込でエラーメッセージを見ることができ、きれいに終了します。 stacktrace(xdebugがオン)で、var_dumpは結果がFALSEであることを示します。ここではテストがある:

public function testGetType() 
{ 
    ... 

    $fragment->setParsed(array()); 
    \PHPUnit_Framework_Error_Warning::$enabled = FALSE; 
    $actual = $fragment->getType(); 
    \PHPUnit_Framework_Error_Warning::$enabled = TRUE; 
    $this->assertLastError('Invalid State Error FAIL', 'Fragment.php'); 
} 

これは私がちょうど書いた新しいテストで、私は他の場所で同じ主張を持っており、彼らは同様にもはや動作しません。

PHPUnit 3.6.7

+0

コードでカスタムエラーハンドラ(set_error_handler)を設定しましたか?それが働いたときにxdebugを有効にしましたか? – meze

+0

(自分のコードで)カスタムエラーハンドラがありません。 xdebugが有効になっていたかどうかはわかりません。以前のPHPUnitバージョンのxdebug非アクティブ化を手動で無効にしました。私のdev xdebugはデフォルトで無効になっています。したがって、xdebugが有効になった可能性は高いですが、私は特に覚えていません。私はどういうわけか、私の制約条件をテストしないために価格を支払っていると感じています。 – hakre

+0

最初にエラーが発生していますか? PHPUnitの警告から例外への変換を無効にしないとどうなりますか? –

答えて

3

これで解決できました。これはPHPUnitをアップグレードしたことに関連しており、APIが少し変更されました。私は自分の制約のためのパターンとしてPHPUnit_Framework_Constraintを取ってきました。そこにあるコメントを読んで助けてください。

ここではの機能が異なります。評価ロジックをプライベート関数に変更し、evaluateからmatchesに切り替えました。それは戻り値で機能します。 evaluateはデフォルトでは戻り値では動作しませんが、例外がスローされることが予想されます。完全に恩恵を受けるには、コンパレータオブジェクトをインスタンス化することもできますが、これは私の頭の中にあったものです。詳細については、asserEqualsの制約を参照してください。

class ConstraintLastError extends \PHPUnit_Framework_Constraint { 

    ... 

    /** 
    * Evaluates the constraint for parameter $file. Returns TRUE if the 
    * constraint is met, FALSE otherwise. 
    * 
    * This method can be overridden to implement the evaluation algorithm. 
    * 
    * @param mixed $other Value or object to evaluate. 
    * @return bool 
    */ 
    public function matches($file) 
    {  
     return $this->compareAgainstLast($file, $this->error); 
    } 

    /** 
    * 
    * @param string $file 
    * @param string $error 
    * @return bool 
    */ 
    private function compareAgainstLast($file, $error) 
    { 
     if (!$last = error_get_last()) 
     { 
      $last = array('message' => '(none)', 'file' => ''); 
     } 

     $this->lastError = $last['message']; 
     $this->lastFile = $last['file']; 

     return $error === $this->lastError && basename($file) === basename($this->lastFile); 
    } 

    /** 
    * @param string $file 
    */ 
    protected function failureDescription($file) 
    { 
     return sprintf('the last error is "%s" in %s, was "%s" in %s' 
        , $this->error, basename($file) 
        , $this->lastError, basename($this->lastFile) 
       ); 
    } 

    ... 

今は魔法のように動作:

1) FragmentTest::testGetType 
Failed asserting that the last error is "Suboptimal State Error" in Fragment.php, was "Invalid State Error" in Fragment.php. 

他の人は、それがベースクラスPhake Fixes issues #43 and #44に実装されていますので、あなたが同様に呼び出すことができます同様の問題が、failへの切り替え別のソリューションを持っていました。

+0

私にはうまく見えます。 - > failは途中でphpunits自身の制約にも使われています:https://github.com/sebastianbergmann/phpunit/blob/3.6/PHPUnit/Framework/Constraint/IsIdentical.php - コンパイラはPHPを手に入れるのに大いに役立ちます'=='振る舞いはまっすぐです(https://github.com/sebastianbergmann/phpunit/blob/3.6/PHPUnit/Framework/Constraint/IsEqual.php参照)が、あなたの場合は必要ありません。共有ありがとう: – edorian

+0

@edorian:フィードバックいただきありがとうございます。 PHPUnitにそのようなアサーションを提案する価値はあると思いますか? (私はすでにそれを少し変更していますので、実際のエラーメッセージに重点を置いて、オプションでfilenameオプションなど、もっと便利です)。 – hakre

+0

私はPHPUnit_Framework_Error_Warning :: $を有効にして、* * @expectedExceptionを残しているとは思っていません。PHPUnit_Framework_Error_Warnings * @expectExceptionMessage myExcpetedErrorMessage'は、これらのケースに対して推奨されるもので、ユーザーに別のオプションを与えることは、それ。私は間違いなくあなたのユースケースを見ることができますが、それは多くの人々に当てはまるとは思いません。しかし、それは間違っているかもしれません。誰もが判断するのはいつものことです:)たぶん、ある時代の世論調査があります:) – edorian

関連する問題