2012-07-31 8 views
6

Come posso scrivere un'asserzione personalizzata, come assertFoo($expected, $actual), che si comporta come le asserzioni predefinite rispetto all'errore "stack trace"?Come scrivere asserzione PHPUnit personalizzata che si comporta come un'asserzione incorporata?

ho attualmente il seguente metodo definito (all'interno di una classe che estende PHPUnit_Framework_TestCase):

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

Se chiamo questo da un test e il test fallisce, ottengo due elementi nello stack di chiamata:

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 riga 17 è dove assertFoo() chiama il numero assertEquals() integrato e ha esito negativo; linea 136 è lì assertFoo() è chiamato.

Se cambio il test di chiamare assertEquals() direttamente, ho solo uno:

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

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

C'è un po 'documentation in the manual, ma non sembra per coprire questo.

+0

Puoi mostrare il codice per la tua funzione assertFoo(). –

+0

@DarrenCook Certo, aggiornato. – mjs

risposta

3

La mia prima ipotesi del problema (che non si sta utilizzando uno degli oggetti PHPUnit_Framework_Constraint_* e self::assertThat) risultava completamente irrilevante! La risposta effettiva è che phpUnit filtra via via dallo stack trace qualsiasi cosa nella propria base di codice, e lascia le funzioni nello spazio utente!

Il codice che fa questo può essere trovato in /path/to/PHPUnit/Util/Filter.php (dove /path/to/ è /usr/share/php sulla mia macchina) e le funzioni di interesse sono getFilteredStacktrace e isFiltered.

Se si desidera controllare questo comportamento, quindi inserire le asserzioni personalizzate in una classe derivata da PHPUnit_Framework_TestCase, quindi derivare i test da quella classe. Nel file di classe personalizzato mettere una chiamata da qualche parte per addFileToFilter, come illustrato di seguito:

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

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

Poi in un altro file si dispone di:

class CustomTest extends My_Base_TestCase{ 

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

e si comporterà esattamente come il built-in assertEquals().

DISCLAIMER: sta utilizzando un comportamento non documentato! Cercherò di scoprire se questo meccanismo sarà ragionevolmente a prova di futuro.

+1

Sfortunatamente, sembra che 'PHPUnit_Util_Filter :: addFileToFilter()' sia scomparso in 3.5. Il modo 3.6 sembra usare 'PHPUnit_Util_GlobalState :: phpunitFiles()' per capire quali file rimuovere, che è statico statico tutto il modo ... Non riesco a vedere alcun modo per modificare il comportamento 'PHPUnit_Util_Filter :: getFilteredStacktrace()' in 3.6. – mjs

+0

@mjs Ha! Per niente a prova di futuro quindi, scusa !! Avrei dovuto dire che stavo guardando phpUnit 3.4.5. Se avrò la possibilità, domani darò un'occhiata all'ultima phpUnit. –

+0

Risulta in PHPUnit 6, devi '\ PHPUnit \ Util \ Blacklist :: $ blacklistedClassNames ['My_Base_TestCase'] = 1;' –