2012-07-31 26 views
6

¿Cómo puedo escribir una afirmación personalizada, como assertFoo($expected, $actual), que se comporta como las aserciones incorporadas con respecto al error "stack trace"?¿Cómo escribir una aserción PHPUnit personalizada que se comporte como una aserción incorporada?

que actualmente tiene definido el siguiente método (dentro de una clase que se extiende PHPUnit_Framework_TestCase):

public static function assertFoo($expected, $actual) { 
    self::assertEquals($expected, $actual); 
} 

Si llamo a esto desde una prueba y la prueba falla, consigo dos elementos de la pila de llamadas:

1) PreferencesTest::testSignupTeacher 
Failed asserting that 5 matches expected 3. 

/vagrant/myproject/tests/integration/PreferencesTest.php:17 
/vagrant/myproject/tests/integration/PreferencesTest.php:136 

La línea 17 es donde assertFoo() llama al assertEquals() incorporado y falla; línea 136 allí assertFoo() se llama.

Si cambio de la prueba para llamar directamente assertEquals(), solo me dan una:

1) PreferencesTest::testSignupTeacher 
Failed asserting that 3 is true. 

/vagrant/myproject/tests/integration/PreferencesTest.php:136 

Hay un poco de documentation in the manual, pero no parece cubrir esto.

+0

Puede mostrar el código de su función assertFoo(). –

+0

@DarrenCook Seguro, actualizado. – mjs

Respuesta

3

Mi primera conjetura del problema (que no está utilizando uno de los objetos PHPUnit_Framework_Constraint_* y self::assertThat) resultó ser completamente irrelevante! La respuesta real es que phpUnit se separa de la pila de cualquier elemento en su propia base de código, y simplemente deja las funciones en el espacio de usuario.

El código que hace esto se puede encontrar en /path/to/PHPUnit/Util/Filter.php (donde /ruta/a/ es /usr/share/php en mi máquina) y las funciones de interés son getFilteredStacktrace y isFiltered.

Si desea controlar este comportamiento, coloque sus afirmaciones personalizadas en una clase derivada de PHPUnit_Framework_TestCase, luego obtenga sus pruebas de esa clase. En el archivo de clase personalizada poner una llamada en algún lugar para addFileToFilter, como se muestra aquí:

class My_Base_TestCase extends PHPUnit_Framework_TestCase{ 
    public static function assertFoo($expected, $actual) { 
    self::assertEquals($expected, $actual); 
    } 
} 

PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT'); 

Luego, en otro archivo que tenga:

class CustomTest extends My_Base_TestCase{ 

    /** */ 
    public function testSomething2(){ 
    $this->assertFoo(8, 5+4); 
    } 
} 

y se comportará igual que el incorporado en assertEquals().

DESCARGO DE RESPONSABILIDAD: ¡Esto está usando un comportamiento no documentado! Voy a tratar de averiguar si este mecanismo va a ser razonablemente a prueba de futuro.

+1

Desafortunadamente, parece que 'PHPUnit_Util_Filter :: addFileToFilter()' desapareció en 3.5. La forma 3.6 parece usar 'PHPUnit_Util_GlobalState :: phpunitFiles()' para determinar qué archivos eliminar, que es estático estático estático en todo momento ... No veo ninguna manera de modificar el comportamiento 'PHPUnit_Util_Filter :: getFilteredStacktrace()' en 3.6. – mjs

+0

@mjs ¡Ja! Para nada a prueba de futuro, ¡perdón! Debería haber dicho que estaba viendo phpUnit 3.4.5. Si tengo la oportunidad, echaré un vistazo con la última versión de phpUnit mañana. –

+0

Resulta en PHPUnit 6, tiene que hacer '\ PHPUnit \ Util \ Blacklist :: $ blacklistedClassNames ['My_Base_TestCase'] = 1;' –

Cuestiones relacionadas