• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Mocking Objects Practices
 

Mocking Objects Practices

on

  • 2,076 views

I test unitari sono sempre più utilizzati per verificare la correttezza del codice che scriviamo. ...

I test unitari sono sempre più utilizzati per verificare la correttezza del codice che scriviamo.
Ci si trova però a volte di fronte a codice scritto in maniera poco "disaccoppiata". Questo può impedirci di sostituire a runtime dei Dependent-on Object con dei Mock Object o degli Stub. Nel talk descriverò un plugin scritto per symfony (ma utilizzabile anche in altri ambiti) che permette di sostituire delle classi a runtime ridefinendole e configurandole all'interno dei test, creando un ambiente che isola il codice da verificare.

Il talk prevederà degli esempi pratici di utilizzo dello strumento descritto.

Statistics

Views

Total Views
2,076
Views on SlideShare
2,052
Embed Views
24

Actions

Likes
1
Downloads
7
Comments
0

2 Embeds 24

http://www.phpday.it 14
http://www.slideshare.net 10

Accessibility

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Mocking Objects Practices Mocking Objects Practices Presentation Transcript

    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Mocking objects practices for Symfony
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it>
      • Come si capisce che il nostro software funziona?
      • Il TDD
      • Centinaia, decine, unità
      • “ L'unità” fa la forza
      • Quando è difficile eseguire uno unit test
      • Esempi pratici di testing con Symfony
        • Lime
        • PHPUnit
        • idMockStunGenerator
      Nei prossimi 50 minuti...
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> is_int (2147483647) + 1 = is_int(2147483648) True False Chi esegue delle verifiche (di qualsiasi tipo) dopo aver scritto del codice??
      • 1° La razza umana è “error prone”
        • 2° Tool
        • 3° Automazione
      Fondamentale: Il codice non è mai privo di errori!! Un esempio: Chi ha mai testato una funzione di somma?
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it>
            • Tutti verifichiamo che il codice che scriviamo funziona
            • Il TDD si usa anche in ambienti non “agili”
      Test-Driven Development Il TDD in un'immagine: Cosa devo fare? (Design) Implementazione Lancio il test Verificato Refactoring Fallito Scrittura Test(s)
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> I test deveno essere il “più possibile” completi Rappresentano le nostre conoscenze (in quel momento) I test rappresentano lo stato del nostro lavoro Abbiamo introdotto errori? Niente test, niente commit. Il refactoring rende il codice pulito , comprensibile e modificabile Spaghetti code, $pippo = $k + $i??? l l Domain-driven Design rende il codice leggibile function PippoPlutoPaperino() VS function getAllButTopolino() Utilizzando il Test-Driven Development...
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it>
      • Bad
      • Tanti utenti => tanti bug/errori
      • I minuti persi
      • Good
      • I test
      • Il metodo di risoluzione dei bug/errori
      Centinaia, ...
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it>
      • Bad
      • Le nuove porzioni di software senza test
      • Modifiche che introducono errori
      • Good
      • Lanciare i test spesso
      • I test ci salvano dall'introduzione di errori involontari
      Decine, ...
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it>
      • Bad
      • Un getter è banale
      • Funzione di somma?
      • Good
      • Internamente le nostre classi/funzioni si comportano correttamente
      • Le nostre classi/funzioni comunicano con l'esterno nella maniera corretta
      • Aiutano ad individuare problemi di integrazione
      Unità.
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Un test unitario specifica il comportamento di un metodo/una funzione o un'intera classe Un test unitario è necessariamente un test isolato Un test unitario rende esplicite le dipendenze di un metodo/oggetto rispetto ad altri metodi/oggetti Un test unitario deve prevedere la verifica di ogni comportamento dell'unità che verifica (“black box” test VS “white box” test) “ L'unità” fa la forza
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Dipendenze ? Disaccoppiamento? Isolamento? Quando è difficile eseguire un test unitario
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it>
      • Scrivere classi che siano disaccoppiate dalle loro dipendenze:
          • Dipendenze passate nel costruttore
              • Public function __constructor() { ...
              • Public function __constructor(Dipendenza dip, ....) { ...
          • Dipendenze passate attraverso chiamate a metodi
              • Public function foo() { $dep = new Dependency(); ....
              • Public function foo(Dependency $dep) { ....
      • Usare Mock e Stub:
          • Replicano i comportamenti delle classi reali
          • Configurabili da chi scrive il test
      Soluzioni per eseguire dei test in isolamento
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it>
      • Come verifichiamo che i risultati ottenuti siano esatti?
          • Stub : verifica dello stato
          • Mock : Verifica del comportamento
      • Due tipi di TDD
          • Il TDD “ classico ” : mock/stub quando è compleso utilizzare le reali dipendenze.
          • Il TDD “ Mockist ” : usare sempre dei mock/stub
      Mock & Stub ref: Mock aren't Stubs <Martin Fowler> http://martinfowler.com/articles/mocksArentStubs.html
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Legacy system/code Gli strumenti con cui lavoro (framework) mi “impongono” la struttura del codice altri??... La decisione all'atto della progettazione non mi permette di applicare i pattern che prevedono mock e stub E quando non posso modificare il codice che verifico??
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Il database è spesso coinvolto E' permesso fare questo: require_once($sf_symfony_lib_dir.'/autoload/sfSimpleAutoload.class.php'); $autoload = new sfSimpleAutoload(); $autoload->addDirectory($sf_symfony_lib_dir.'/util'); $autoload->register(); E questo: new sfDatabaseManager(ProjectConfiguration::getApplicationConfiguration( 'frontend', 'test', true)); $loader = new sfPropelData(); $loader->loadData(sfConfig::get('sf_data_dir').'/fixtures'); Symfony e unit test
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Lime style: include(dirname(__FILE__).'/../bootstrap/unit.php'); require_once($sf_symfony_lib_dir.'/util/sfToolkit.class.php'); class myObject { public function myMethod(){} } $t = new lime_test(16, new lime_output_color()); $t->diag('isPathAbsolute()'); $t->is(sfToolkit::isPathAbsolute('/test'), true); $t->ok(sfToolkit::setObject(new myObject()) instanceof myObject); Symfony e unit test
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> sfPhpunitPlugin class RepositoryTest extends PHPUnit_Framework_TestCase{ public function testGetLogFromRepository() { $proxy = $this->getMock('SvnProxy'); $xml_reader = $this->getMock('SvnXmlReader'); $logcommand = $this->getMock('SvnLogCommand'); $repository = new SVNRepository($proxy, $xml_reader); $this->assertEquals('svn log -n 5', $repository->getRevisionsLog($mock_logcommand)); } … } Symfony e unit test
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> idMockStubGenerator include('/Mock-Stub-Generator/FakeObjectGenerator.cless.php'); $rvm = new ReturnValuesManager('SvnLogCommand'); $rvm->setReturnValue('getSubCommandName', 'subCommandName ') ->setReturnValue('getOptionList', '--option value --option value '); FakeObjectGenerator::generate($rvm, new CodeGenerator()); $t = new lime_test(9, new lime_output_color()); $svn_proxy = new SvnProxy('file:///localrepository/newProject'); $svn_proxy->setSubCommand(new SvnLogCommand()); $t->is($svn_proxy->getCommand(), 'svn --config-dir subCommandName --option value --option value '); Symfony e unit test
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Un esempio vale più di mille parole!
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Non utilizzando le classi reali, come faccio ad implementare uno unit test per la mia classe SvnRepository? Lime? PHPUnit? idMockStubGenerator? Sto sviluppando un “lettore” di log di un repository SVN remoto Ho bisogno di una classe per la lettura dei file XML. Ho bisogno di una classe per la gestione del comando SVN Ho bisogno di due classi per icomandi “log” e “diff” Ho bisogno di una classe che faccia da parser per i file diff Ho bisogno di una classe che descrive i dati ricavati dai log
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Come faccio a replicare le classi “Peer” generate da propel? Lime? PHPUnit? idMockStubGenerator? Sto sviluppando due classi “user” e “book” usando Symfony e propel Ho una classe utenti Ho una classe libri Voglio cercare un libro il cui titolo è uguale al mio nome
    • Mocking Object practices for Symfony Filippo De Santis <fd@ideato.it> Domande?