Mocking Objects Practices

download Mocking Objects Practices

If you can't read please download the document

description

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.

Transcript of Mocking Objects Practices

  • 1. Mocking Object practices for Symfony Filippo De Santis Mocking objects practices for Symfony

2. Mocking Object practices for Symfony Filippo De Santis

  • 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... 3. Mocking Object practices for Symfony Filippo De Santis 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? 4. Mocking Object practices for Symfony Filippo De Santis

        • 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) 5. Mocking Object practices for Symfony Filippo De Santis Itestdeveno essere ilpi possibile completi Rappresentano le nostre conoscenze (in quel momento) Itestrappresentanolostato del nostro lavoro Abbiamo introdotto errori? Niente test, niente commit. Ilrefactoringrende ilcodice pulito ,comprensibileemodificabile Spaghetti code, $pippo = $k + $i??? l lDomain-driven Designrende ilcodice leggibile function PippoPlutoPaperino() VS function getAllButTopolino() Utilizzando il Test-Driven Development... 6. Mocking Object practices for Symfony Filippo De Santis

  • Bad
  • Tanti utenti => tanti bug/errori
  • I minuti persi
  • Good
  • I test
  • Il metodo di risoluzione dei bug/errori

Centinaia, ... 7. Mocking Object practices for Symfony Filippo De Santis

  • 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, ... 8. Mocking Object practices for Symfony Filippo De Santis

  • 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. 9. Mocking Object practices for Symfony Filippo De Santis Un test unitario specifica ilcomportamentodi un metodo/una funzione o un'intera classe Un test unitario necessariamente un testisolato Un test unitario rende esplicite ledipendenzedi un metodo/oggetto rispetto ad altri metodi/oggetti Un test unitario deve prevedere la verifica diognicomportamento dell'unit che verifica (black box test VS white box test) L'unit fa la forza 10. Mocking Object practices for Symfony Filippo De Santis Dipendenze ? Disaccoppiamento? Isolamento? Quando difficile eseguire un test unitario 11. Mocking Object practices for Symfony Filippo De Santis

  • 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
          • Publicfunction foo() { $dep = new Dependency();....
          • Publicfunction 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 12. Mocking Object practices for Symfony Filippo De Santis

  • 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 http://martinfowler.com/articles/mocksArentStubs.html 13. Mocking Object practices for Symfony Filippo De Santis 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?? 14. Mocking Object practices for Symfony Filippo De Santis 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 15. Mocking Object practices for Symfony Filippo De Santis 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 16. Mocking Object practices for Symfony Filippo De Santis 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 17. Mocking Object practices for Symfony Filippo De Santis 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 18. Mocking Object practices for Symfony Filippo De Santis Un esempio vale pi di mille parole! 19. Mocking Object practices for Symfony Filippo De Santis 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 20. Mocking Object practices for Symfony Filippo De Santis 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 21. Mocking Object practices for Symfony Filippo De Santis Domande?