2012-01-23 11 views
6

estoy tratando de agregar una aserción costumbre de PHPUnit, siguiendo this tutorial, para validar los números complejos devueltos como una cadena (por ejemploencargo PHPUnit afirma necesitaba ayuda

"-123 + 456i"

por el método que estoy probando) con una precisión definida para los componentes tanto reales como imaginarios. He puesto una clase Complex.php analizar la cadena en las partes real e imaginaria, y poner juntos la siguiente afirmación de la clase como complexAssert.php:

require_once 'PHPUnit/Framework/Assert.php'; 
include_once getcwd().'/custom/Complex.php'; 

class complexAssert extends PHPUnit_Framework_Assert { 

    public function assertComplexEquals($expected, $actual, $message = '', $delta = 0) 
    { 
     $expectedComplex = new Complex($expected); 
     $actualComplex = new Complex($actual); 

     if (!($actualComplex->getReal() >= ($expectedComplex - $delta) && 
      $actualComplex->getReal() <= ($expectedComplex + $delta))) { 
      return $this->fail($message); 
     } 

     if (!($actualComplex->getImaginary() >= ($expectedComplex - $delta) && 
      $actualComplex->getImaginary() <= ($expectedComplex + $delta))) { 
      return $this->fail($message); 
     } 

    } 
} 

Mi script de prueba de unidad:

require_once getcwd().'/custom/complexAssert.php'; 
require_once 'testDataFileIterator.php'; 

class EngineeringTest extends PHPUnit_Framework_TestCase 
{ 
    /** 
    * @dataProvider providerIMSUM 
    */ 
    public function testIMSUM() 
    { 
     $args = func_get_args(); 
     $expectedResult = array_pop($args); 
     $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args); 
     $this->assertComplexEquals($expectedResult, $result); 
    } 

    public function providerIMSUM() 
    { 
     return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data'); 
    } 
} 

Las pruebas unitarias funcionaron sin error (pero fallaron) cuando simplemente estaba haciendo un assertEquals ... pero ahora he agregado el include y cambiado a mi nueva afirmación, se está bloqueando al afirmar que no puede llamar al método undefined assertComplexEquals ()

¿Alguien ha tenido éxito al extender phpunit con afirmaciones personalizadas, y puede ver lo que estoy haciendo mal?

+0

Usted podría mejor seguir el oficial http://www.phpunit.de/manual/current/en/extending-phpunit.html#extending-phpunit.custom-assertions – zerkms

+2

Si bien no está relacionado con este problema, es posible que desee utilizar '__DIR__' (PHP 5.3 +) o 'dirname (__ FILE __)' en lugar de de pendiente en el directorio de trabajo actual que puede cambiar mientras se ejecuta el programa. –

+0

@David Harkness: Apuesto a que en su caso 'getcwd()! = __DIR__' – zerkms

Respuesta

0

Al final, he elegido no extender existente afirma sino modificar mi lógica afirmación complejo para devolver un valor booleano simple, que podría luego se probará usando assertTrue(), y con un mensaje de error que se podría recuperar con un simple getMessage() para mostrar en los resultados de phpunit. Para ser honesto, se siente mucho más fácil de usar de esta manera

include_once __DIR__.'/Complex.php'; 

class complexAssert { 

    private $_errorMessage = ''; 

    public function assertComplexEquals($expected, $actual, $delta = 0) 
    { 
     $expectedComplex = new Complex($expected); 
     $actualComplex = new Complex($actual); 

     if ($actualComplex->getReal() < ($expectedComplex->getReal() - $delta) || 
      $actualComplex->getReal() > ($expectedComplex->getReal() + $delta)) { 
      $this->_errorMessage = 'Mismatched Real part: ' . 
            $actualComplex->getReal() . 
            ' !== ' . 
            $expectedComplex->getReal(); 
      return FALSE; 
     } 

     if ($actualComplex->getImaginary() < ($expectedComplex->getImaginary() - $delta) || 
      $actualComplex->getImaginary() > ($expectedComplex->getImaginary() + $delta)) { 
      $this->_errorMessage = 'Mismatched Imaginary part: ' . 
            $actualComplex->getImaginary() . 
            ' !== ' . 
            $expectedComplex->getImaginary(); 
      return FALSE; 
     } 

     return TRUE; 
    } 

    public function getErrorMessage() { 
     return $this->_errorMessage; 
    } 
} 

Mi script de prueba de unidad:

// Custom assertion class for handling precision of Complex numbers 
require_once __DIR__.'/../../custom/complexAssert.php'; 
// Data Provider handler 
require_once 'testDataFileIterator.php'; 

class EngineeringTest extends PHPUnit_Framework_TestCase 
{ 
    /** 
    * @dataProvider providerIMSUM 
    */ 
    public function testIMSUM() 
    { 
     $args = func_get_args(); 
     $expectedResult = array_pop($args); 
     $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args); 
     $complexAssert = new complexAssert(); 
     $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8), 
          $complexAssert->getErrorMessage()); 
    } 

    public function providerIMSUM() 
    { 
     return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data'); 
    } 
} 

y el resultado PHPUnit registrado es suficientemente claro:

3) EngineeringTest::testIMSUB with data set #7 ('-12.34-5.67i', '-123.45-67.89', '#NUM!') 
Mismatched String: 111.11 !== #NUM! 
Failed asserting that false is true. 
1

Obviamente, la única forma de obtener $this->someCustomAssertion funcionó es ampliar PHPUnit_Framework_TestCase y crear métodos wrapper allí, o llamar a sus aserciones personalizadas estáticamente.

Zend Framework, por ejemplo, simplemente se extiende PHPUnit_Framework_TestCase con métodos adicionales (afirmaciones)