SlideShare a Scribd company logo
1 of 93
Download to read offline
Mocking
 Demystified

               by @_md
how many of you
  write tests?
how many
write tests before the code?
how many of you
know what a mock is?
how many of you use mocks?
ALL YOU NEED TO KNOW ABOUT TESTING
           (in 5 minutes)
test

Arrange

          Act

                 Assert
test
        instantiate
Arrange
        tested object
       Act

              Assert
instantiate
          Arrange
                  tested object

$parser = new MarkdownParser;
test

Arrange
                  run the method
          Act     you want to test
                 Assert
run the method
          Act
                  you want to test

$parser = new MarkdownParser;

$html = $parser->toHtml('Hello World');
test

Arrange

          Act

                 Assert specify the
                        expected outcome
specify the
          Assert
                 expected outcome

$parser = new MarkdownParser;
$html = $parser->toHtml('Hello World');

assertTrue('<p>Hello World</p>' == $html);
test

Arrange         instantiate tested object

          Act        run the method

                Assert      check expected outcome
$this->toHtml('Hello World')
     ->shouldReturn('<p>Hello World</p>');
$this->toHtml('Hello World')
     ->shouldReturn('<p>Hello World</p>');




     a test is an executable example
      of a class expected behaviour
READY TO MOCK AROUND?
why?
class ParserSubject
{
    public function notify(Event $event)
    {
        foreach ($this->subscribers as $subscriber) {
            $subscriber->onChange($event);
        }
    }

}




                                 HOW DO I KNOW NOTIFY WORKS?
class ParserSubjectTest extends TestCase
{
    /** @test */
    function it_notifies_subscribers()
    {
         // arrange
        $parser = new ParserSubject;

        // act
        // I need an event!!!
        $parser->notify(/* $event ??? */);

        // assert
        // how do I know subscriber::onChange got called?
    }

}



                                 HOW DO I KNOW NOTIFY WORKS?
class EndOfListListener extends EventListener
{

    public function onNewLine(Event $event)
    {
        $html = $event->getText();
        if ($this->document->getNextLine() == "") {
            $html .= "</li></ul>";
        }
        return $html;
    }

}




                          HOW DO I CONTROL EVENT AND DOCUMENT
{
                  focus on unit
                  expensive to instantiate
      why?        control on collaborators’ state
                  indirect outputs
                  undesirable side effects
[Meszaros 2007]
a mock is just 1 of
many test double patterns
doubles are replacement of anything
    that is not the tested object
{
                       dummy
                       fake
             doubles   stub
                       mock
                       spy
[Meszaros 2007]
{
                  dummy no behaviour
                  fake
                         control indirect output
    doubles       stub
                  mock
                        check indirect output
                  spy
[Meszaros 2007]
a mockist TDD, London school, approach:


only the tested object is real
DOUBLES WITHOUT BEHAVIOUR
dummy




http://wicker123.deviantart.com/art/Slappy-The-Dummy-148136425
test

Arrange

          Act

                 Assert
arrange
          {
          instantiate (may require collaborators)
class MarkdownParser
{
    private $eventDispatcher;

    public function __construct(EventDispatcher $dispatcher)
    {
        $this->eventDispatcher = $dispatcher;
    }
}




                                USE DOUBLES TO BYPASS TYPE HINTING
class MarkdownParser
{
    private $eventDispatcher;

    public function __construct(EventDispatcher $dispatcher)
    {
        $this->eventDispatcher = $dispatcher;
    }
}




                                USE DOUBLES TO BYPASS TYPE HINTING
class MarkdownParserTest extends TestCase
{

    function setUp()
    {
        $dispatcher = $this->getMock('EventDispatcher');
        $this->parser = new MardownParser($dispatcher);
    }

}




                                               XUNIT EXAMPLE
class MarkdownParser extends ObjectBehavior
{

    function let($dispatcher)
    {
        $dispatcher->beAMockOf('EventDispatcher');
        $this->beConstructedWith($dispatcher);
    }

}




                                              PHPSPEC EXAMPLE
http://wicker123.deviantart.com/art/Slappy-The-Dummy-148136425
      “Dummy is a placeholder passed to the
       SUT (tested object), but never used”

[Meszaros 2007]
dummy: double with no behaviour




http://wicker123.deviantart.com/art/Slappy-The-Dummy-148136425
DOUBLES TO CONTROL INDIRECT OUPUT
arrange
          {
          instantiate (may require collaborators)
          further change state
class MarkdownParserTest extends TestCase
{

    function setUp()
    {
        $dispatcher = $this->getMock('EventDispatcher');
        $this->parser = new MardownParser($dispatcher);

        $this->parser->setEncoding('UTF-8');

    }

}




                         FURTHER CHANGE TO THE STATE IN ARRANGE
class MarkdownParserTest extends TestCase
{

    function setUp()
    {
        $dispatcher = $this->getMock('EventDispatcher');
        $this->parser = new MardownParser($dispatcher);

        $this->parser->setEncoding('UTF-8');

    }

}




                         FURTHER CHANGE TO THE STATE IN ARRANGE
arrange
          {
          instantiate (may require collaborators)
          further change state
          configure indirect output
class EndOfListListener extends EventListener
{

    public function onNewLine(Event $event)
    {
        $html = $event->getText();
        if ($this->document->getNextLine() == "") {
            $html .= "</li></ul>";
        }
        return $html;
    }

}




                                            INDIRECT OUTPUTS
class EndOfListListener extends EventListener
{

    public function onNewLine(Event $event)
    {
        $html = $event->getText();
        if ($this->document->getNextLine() == "") {
            $html .= "</li></ul>";
        }
        return $html;
    }

}




                                            INDIRECT OUTPUTS
fake
stub
                                        doubles for controlling indirect output




       http://www.flickr.com/photos/fcharlton/1841638596/
       http://www.flickr.com/photos/64749744@N00/476724045
$event->getText(); // will return “Hello World”
$this->document->getNextLine(); // will return “”




                 STUBBING: CONTROLLING DOUBLES INDIRECT OUTPUTS
function let($event, $document)
{
    $event->beAMockOf("Event");
    $document->beAMockOf("Document");
    $this->beConstructedWith($document);
}




                                           IN PHPSPEC
function let($event, $document)
{
    $event->beAMockOf("Event");
    $document->beAMockOf("Document");
    $this->beConstructedWith($document);
}

function it_ends_list_when_next_is_empty($event, $document)
{
    $event->getText()->willReturn("Some text");
    $document->getNextLine()->willReturn("");




}




                                                   IN PHPSPEC
function let($event, $document)
{
    $event->beAMockOf("Event");
    $document->beAMockOf("Document");
    $this->beConstructedWith($document);
}

function it_ends_list_when_next_is_empty($event, $document)
{
    $event->getText()->willReturn("Some text");
    $document->getNextLine()->willReturn("");

    $this->onNewLine($event)
         ->shouldReturn("Some text</li></ul>");

}




                                                   IN PHPSPEC
class EndOfListListener extends EventListener
{

    public function onNewLine(Event $event)
    {
        $html = $event->getText();
        if ($this->document->getNextLine() == "") {
            $html .= "</li></ul>";
        }
        return $html;
    }

}




                                                THE CODE AGAIN
function let($event, $document)
{
    $event->beAMockOf("Event");
    $document->beAMockOf("Document");
    $this->beConstructedWith($document);
}

function it_ends_list_when_next_is_empty($event, $document)
{
    $event->getText()->willReturn("Some text");
    $document->getNextLine()->willReturn("");

    $this->onNewLine($event)
         ->shouldReturn("Some text</li></ul>");

}




                                                  THE SPEC AGAIN
double                       behaviour

loose demand       returns null to any method call
fake           returns null to defined set methods
stub           returns value defined or raise error
DOUBLES TO SPEC MESSAGE EXCHANGE
we said before

a test is an executable example
 of a class expected behaviour
what is behaviour?
B = I + O


 behaviour = input + output
what can happen in a method?
{
          return a value
          modify state
methods   print something
          throw an exception
          delegate
{
          return a value
                          not the final
          modify state
                            behaviour
methods   print something
          throw an exception
          delegate
{
methods
          return a value we should probably
          print something delegate that too
          throw an exception
          delegate
{
methods
          return a value
          throw an exception
          delegate
method                strategy

returns a value
throws an exception

delegates
method                     strategy

returns a value         assertions/
throws an exception    expectations

delegates             mocks & spies
Viewpoints Research Institute Source - Bonnie Macbird URL -http://www.vpri.org
“The key in making great and growable systems is much more to
         design how its modules communicate
          rather than what their internal properties
                  and behaviours should be.”

                        Messaging
messaging
yeah, but what does it mean?
$this->person->getCar()->getEngine()->ignite();
Inappropriate Intimacy
$this->person->startCar();
tell, don’t ask!


[Sharp 1997]
exposing lower level implementation
       makes the code rigid
$this->person->getCar()->getEngine()->ignite();
focus on messaging
makes the code flexible
$this->person->startCar();
mock
spy
                                              doubles for messaging




               http://www.flickr.com/photos/scribe215/3234974208/
       http://www.flickr.com/photos/21560098@N06/5772919201/
class ParserSubject
{
    public function notify(Event $event)
    {
        foreach ($this->subscribers as $subscriber) {
            $subscriber->onChange($event);
        }
    }

}




                                 HOW DO I KNOW NOTIFY WORKS?
class ParserSubject
{
    public function notify(Event $event)
    {
        foreach ($this->subscribers as $subscriber) {
            $subscriber->onChange($event);
        }
    }

}




                                 HOW DO I KNOW NOTIFY WORKS?
use mocks to describe how your
method will impact collaborators
use PHPUnit_Framework_TestCase as TestCase;

class ParserSubjectTest extends TestCase
{
    /** @test */ function it_notifies_subscribers()
    {
        $event = $this->getMock("Event");

        $subscriber = $this->getMock("Subscriber");
        $subscriber->expects($this->once())
                   ->method("onChange")
                   ->with($event);

        $parser = new ParserSubject();
        $parser->attach($subscriber);
        $parser->notify($event);
    }
}


                           USING PHPUNIT NATIVE MOCK CONSTRUCT
public function testUpdateWithEqualTypes()
{
    $installer = $this->createInstallerMock();
    $manager   = new InstallationManager('vendor');
    $manager->addInstaller($installer);

    $initial   = $this->createPackageMock();
    $target    = $this->createPackageMock();
    $operation = new UpdateOperation($initial, $target, 'test');

    $initial
        ->expects($this->once())
        ->method('getType')
        ->will($this->returnValue('library'));
    $target
        ->expects($this->once())
        ->method('getType')
        ->will($this->returnValue('library'));

    $installer
        ->expects($this->once())
        ->method('supports')
        ->with('library')
        ->will($this->returnValue(true));

    $installer
        ->expects($this->once())
        ->method('update')
        ->with($this->repository, $initial, $target);




                                                                   EXCESSIVE SETUP
github.com/padraicb/mockery
use PHPUnit_Framework_TestCase as TestCase;

class ParserSubjectTest extends TestCase
{
    /** @test */ function it_notifies_subscribers()
    {
        $event = Mockery::mock("Event");

        $subscriber = Mockery::mock("Subscriber");
        $subscriber->shouldReceive("onChange")
                   ->with($event);

        $parser = new ParserSubject();
        $parser->attach($subscriber);
        $parser->notify($event);
    }
}



                                               USING MOCKERY
class ParserSubject extends PHPSpec2ObjectBehavior
{
    /**
      * @param Event $event
      * @param Subscriber $subscriber
      */
    function it_notifies_subscribers($event, $subscriber)
    {
         $subscriber->onChange($event)->shouldBeCalled();
         $this->attach($subscriber);

        $this->notify($event);
    }
}




                                      SAME EXAMPLE IN PHPSPEC
use spies to describe indirect output
   expectations, retrospectively
github.com/dancras/doubles
use PHPSpec2ObjectBehavior;

class ParserSubject extends ObjectBehavior
{
    function it_notifies_subscribers()
    {
        $event = Doubles::fromClass('Event');
        $subscriber = Doubles::fromClass('Subscriber');
        $this->attach($subscriber);
        $this->notify($event);

        $subscriber->spy('onChange')->callCount()->shoudBe(1);

    }
}




                        SPY EXAMPLE – WITH “DOUBLES” FRAMEWORK
use PHPSpec2ObjectBehavior;

class ParserSubject extends ObjectBehavior
{
    /**
      * @param Event $event
      * @param Subscriber $subscriber
      */
    function it_notifies_subscribers($event, $subscriber)
    {
         $this->attach($subscriber);
         $this->notify($event);
         $subscriber->onChange($event)
                    ->shouldHaveBeenCalled();
    }
}




              SPY EXAMPLE – AVAILABLE WITH PROPHECY INTEGRATION
use ProphecyProphet;

class TestCase extends SomeUnitTestingFrameworkTestCase
{
    function createDoubler($name)
    {
        $this->prophet = new ProphecyProphet;
        return $this->prophet->prophesize($name);
    }

    function createDummy($name)
    {
        return $this->createDoubler($name)->reveal();
    }
}




                                         INTEGRATING PROPHECY
{
                  dummy no behaviour
                  fake
                        control indirect output
    doubles       stub
                  mock
                        messaging
                  spy
[Meszaros 2007]
Marcello Duarte

  I work here
I contribute here
  I tweet here @_md
Thank you !
Questions or Comments?




want to improve on testing? bit.ly/inviqa-bdd-training

More Related Content

What's hot

Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Konstantin Kudryashov
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介Jace Ju
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonfRafael Dohms
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix itRafael Dohms
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome TownRoss Tuck
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 

What's hot (20)

Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 

Viewers also liked

Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages webJean-Pierre Vincent
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsDavey Shafik
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phingRajat Pandit
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)Matthias Noback
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performanceafup Paris
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Marcello Duarte
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!tlrx
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLGabriele Bartolini
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Bruno Boucard
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)Arnauld Loyer
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apacheafup Paris
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsRyan Weaver
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 

Viewers also liked (20)

Elastic Searching With PHP
Elastic Searching With PHPElastic Searching With PHP
Elastic Searching With PHP
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
Diving deep into twig
Diving deep into twigDiving deep into twig
Diving deep into twig
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQL
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)
 
Behat 3.0 meetup (March)
Behat 3.0 meetup (March)Behat 3.0 meetup (March)
Behat 3.0 meetup (March)
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apache
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 

Similar to Mocking Demystified

Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
The command dispatcher pattern
The command dispatcher patternThe command dispatcher pattern
The command dispatcher patternolvlvl
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Jason Lotito
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 

Similar to Mocking Demystified (20)

Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Hack tutorial
Hack tutorialHack tutorial
Hack tutorial
 
The command dispatcher pattern
The command dispatcher patternThe command dispatcher pattern
The command dispatcher pattern
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
Smelling your code
Smelling your codeSmelling your code
Smelling your code
 
Php & my sql
Php & my sqlPhp & my sql
Php & my sql
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 

More from Marcello Duarte

Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHPMarcello Duarte
 
Introducing Eager Design
Introducing Eager DesignIntroducing Eager Design
Introducing Eager DesignMarcello Duarte
 
Understanding craftsmanship
Understanding craftsmanshipUnderstanding craftsmanship
Understanding craftsmanshipMarcello Duarte
 
The framework as an implementation detail
The framework as an implementation detailThe framework as an implementation detail
The framework as an implementation detailMarcello Duarte
 
Emergent design with phpspec
Emergent design with phpspecEmergent design with phpspec
Emergent design with phpspecMarcello Duarte
 
Pair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical thingsPair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical thingsMarcello Duarte
 
BDD For Zend Framework With PHPSpec
BDD For Zend Framework With PHPSpecBDD For Zend Framework With PHPSpec
BDD For Zend Framework With PHPSpecMarcello Duarte
 

More from Marcello Duarte (12)

Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHP
 
Empathy from Agility
Empathy from AgilityEmpathy from Agility
Empathy from Agility
 
Introducing Eager Design
Introducing Eager DesignIntroducing Eager Design
Introducing Eager Design
 
Barely Enough Design
Barely Enough DesignBarely Enough Design
Barely Enough Design
 
Transitioning to Agile
Transitioning to AgileTransitioning to Agile
Transitioning to Agile
 
Understanding craftsmanship
Understanding craftsmanshipUnderstanding craftsmanship
Understanding craftsmanship
 
Hexagonal symfony
Hexagonal symfonyHexagonal symfony
Hexagonal symfony
 
The framework as an implementation detail
The framework as an implementation detailThe framework as an implementation detail
The framework as an implementation detail
 
Emergent design with phpspec
Emergent design with phpspecEmergent design with phpspec
Emergent design with phpspec
 
Pair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical thingsPair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical things
 
Deliberate practice
Deliberate practiceDeliberate practice
Deliberate practice
 
BDD For Zend Framework With PHPSpec
BDD For Zend Framework With PHPSpecBDD For Zend Framework With PHPSpec
BDD For Zend Framework With PHPSpec
 

Recently uploaded

Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 

Recently uploaded (20)

Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 

Mocking Demystified

  • 2. how many of you write tests?
  • 3. how many write tests before the code?
  • 4. how many of you know what a mock is?
  • 5. how many of you use mocks?
  • 6. ALL YOU NEED TO KNOW ABOUT TESTING (in 5 minutes)
  • 7. test Arrange Act Assert
  • 8. test instantiate Arrange tested object Act Assert
  • 9. instantiate Arrange tested object $parser = new MarkdownParser;
  • 10. test Arrange run the method Act you want to test Assert
  • 11. run the method Act you want to test $parser = new MarkdownParser; $html = $parser->toHtml('Hello World');
  • 12. test Arrange Act Assert specify the expected outcome
  • 13. specify the Assert expected outcome $parser = new MarkdownParser; $html = $parser->toHtml('Hello World'); assertTrue('<p>Hello World</p>' == $html);
  • 14. test Arrange instantiate tested object Act run the method Assert check expected outcome
  • 15. $this->toHtml('Hello World') ->shouldReturn('<p>Hello World</p>');
  • 16. $this->toHtml('Hello World') ->shouldReturn('<p>Hello World</p>'); a test is an executable example of a class expected behaviour
  • 17. READY TO MOCK AROUND?
  • 18. why?
  • 19. class ParserSubject { public function notify(Event $event) { foreach ($this->subscribers as $subscriber) { $subscriber->onChange($event); } } } HOW DO I KNOW NOTIFY WORKS?
  • 20. class ParserSubjectTest extends TestCase { /** @test */ function it_notifies_subscribers() { // arrange $parser = new ParserSubject; // act // I need an event!!! $parser->notify(/* $event ??? */); // assert // how do I know subscriber::onChange got called? } } HOW DO I KNOW NOTIFY WORKS?
  • 21. class EndOfListListener extends EventListener { public function onNewLine(Event $event) { $html = $event->getText(); if ($this->document->getNextLine() == "") { $html .= "</li></ul>"; } return $html; } } HOW DO I CONTROL EVENT AND DOCUMENT
  • 22. { focus on unit expensive to instantiate why? control on collaborators’ state indirect outputs undesirable side effects [Meszaros 2007]
  • 23. a mock is just 1 of many test double patterns
  • 24. doubles are replacement of anything that is not the tested object
  • 25. { dummy fake doubles stub mock spy [Meszaros 2007]
  • 26. { dummy no behaviour fake control indirect output doubles stub mock check indirect output spy [Meszaros 2007]
  • 27. a mockist TDD, London school, approach: only the tested object is real
  • 30. test Arrange Act Assert
  • 31. arrange { instantiate (may require collaborators)
  • 32. class MarkdownParser { private $eventDispatcher; public function __construct(EventDispatcher $dispatcher) { $this->eventDispatcher = $dispatcher; } } USE DOUBLES TO BYPASS TYPE HINTING
  • 33. class MarkdownParser { private $eventDispatcher; public function __construct(EventDispatcher $dispatcher) { $this->eventDispatcher = $dispatcher; } } USE DOUBLES TO BYPASS TYPE HINTING
  • 34. class MarkdownParserTest extends TestCase { function setUp() { $dispatcher = $this->getMock('EventDispatcher'); $this->parser = new MardownParser($dispatcher); } } XUNIT EXAMPLE
  • 35. class MarkdownParser extends ObjectBehavior { function let($dispatcher) { $dispatcher->beAMockOf('EventDispatcher'); $this->beConstructedWith($dispatcher); } } PHPSPEC EXAMPLE
  • 36. http://wicker123.deviantart.com/art/Slappy-The-Dummy-148136425 “Dummy is a placeholder passed to the SUT (tested object), but never used” [Meszaros 2007]
  • 37. dummy: double with no behaviour http://wicker123.deviantart.com/art/Slappy-The-Dummy-148136425
  • 38. DOUBLES TO CONTROL INDIRECT OUPUT
  • 39. arrange { instantiate (may require collaborators) further change state
  • 40. class MarkdownParserTest extends TestCase { function setUp() { $dispatcher = $this->getMock('EventDispatcher'); $this->parser = new MardownParser($dispatcher); $this->parser->setEncoding('UTF-8'); } } FURTHER CHANGE TO THE STATE IN ARRANGE
  • 41. class MarkdownParserTest extends TestCase { function setUp() { $dispatcher = $this->getMock('EventDispatcher'); $this->parser = new MardownParser($dispatcher); $this->parser->setEncoding('UTF-8'); } } FURTHER CHANGE TO THE STATE IN ARRANGE
  • 42. arrange { instantiate (may require collaborators) further change state configure indirect output
  • 43. class EndOfListListener extends EventListener { public function onNewLine(Event $event) { $html = $event->getText(); if ($this->document->getNextLine() == "") { $html .= "</li></ul>"; } return $html; } } INDIRECT OUTPUTS
  • 44. class EndOfListListener extends EventListener { public function onNewLine(Event $event) { $html = $event->getText(); if ($this->document->getNextLine() == "") { $html .= "</li></ul>"; } return $html; } } INDIRECT OUTPUTS
  • 45. fake stub doubles for controlling indirect output http://www.flickr.com/photos/fcharlton/1841638596/ http://www.flickr.com/photos/64749744@N00/476724045
  • 46. $event->getText(); // will return “Hello World” $this->document->getNextLine(); // will return “” STUBBING: CONTROLLING DOUBLES INDIRECT OUTPUTS
  • 47. function let($event, $document) { $event->beAMockOf("Event"); $document->beAMockOf("Document"); $this->beConstructedWith($document); } IN PHPSPEC
  • 48. function let($event, $document) { $event->beAMockOf("Event"); $document->beAMockOf("Document"); $this->beConstructedWith($document); } function it_ends_list_when_next_is_empty($event, $document) { $event->getText()->willReturn("Some text"); $document->getNextLine()->willReturn(""); } IN PHPSPEC
  • 49. function let($event, $document) { $event->beAMockOf("Event"); $document->beAMockOf("Document"); $this->beConstructedWith($document); } function it_ends_list_when_next_is_empty($event, $document) { $event->getText()->willReturn("Some text"); $document->getNextLine()->willReturn(""); $this->onNewLine($event) ->shouldReturn("Some text</li></ul>"); } IN PHPSPEC
  • 50. class EndOfListListener extends EventListener { public function onNewLine(Event $event) { $html = $event->getText(); if ($this->document->getNextLine() == "") { $html .= "</li></ul>"; } return $html; } } THE CODE AGAIN
  • 51. function let($event, $document) { $event->beAMockOf("Event"); $document->beAMockOf("Document"); $this->beConstructedWith($document); } function it_ends_list_when_next_is_empty($event, $document) { $event->getText()->willReturn("Some text"); $document->getNextLine()->willReturn(""); $this->onNewLine($event) ->shouldReturn("Some text</li></ul>"); } THE SPEC AGAIN
  • 52. double behaviour loose demand returns null to any method call fake returns null to defined set methods stub returns value defined or raise error
  • 53. DOUBLES TO SPEC MESSAGE EXCHANGE
  • 54. we said before a test is an executable example of a class expected behaviour
  • 56. B = I + O behaviour = input + output
  • 57. what can happen in a method?
  • 58. { return a value modify state methods print something throw an exception delegate
  • 59. { return a value not the final modify state behaviour methods print something throw an exception delegate
  • 60. { methods return a value we should probably print something delegate that too throw an exception delegate
  • 61. { methods return a value throw an exception delegate
  • 62. method strategy returns a value throws an exception delegates
  • 63. method strategy returns a value assertions/ throws an exception expectations delegates mocks & spies
  • 64. Viewpoints Research Institute Source - Bonnie Macbird URL -http://www.vpri.org “The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviours should be.” Messaging
  • 66. yeah, but what does it mean?
  • 71. exposing lower level implementation makes the code rigid
  • 73. focus on messaging makes the code flexible
  • 75. mock spy doubles for messaging http://www.flickr.com/photos/scribe215/3234974208/ http://www.flickr.com/photos/21560098@N06/5772919201/
  • 76. class ParserSubject { public function notify(Event $event) { foreach ($this->subscribers as $subscriber) { $subscriber->onChange($event); } } } HOW DO I KNOW NOTIFY WORKS?
  • 77. class ParserSubject { public function notify(Event $event) { foreach ($this->subscribers as $subscriber) { $subscriber->onChange($event); } } } HOW DO I KNOW NOTIFY WORKS?
  • 78. use mocks to describe how your method will impact collaborators
  • 79. use PHPUnit_Framework_TestCase as TestCase; class ParserSubjectTest extends TestCase { /** @test */ function it_notifies_subscribers() { $event = $this->getMock("Event"); $subscriber = $this->getMock("Subscriber"); $subscriber->expects($this->once()) ->method("onChange") ->with($event); $parser = new ParserSubject(); $parser->attach($subscriber); $parser->notify($event); } } USING PHPUNIT NATIVE MOCK CONSTRUCT
  • 80. public function testUpdateWithEqualTypes() { $installer = $this->createInstallerMock(); $manager = new InstallationManager('vendor'); $manager->addInstaller($installer); $initial = $this->createPackageMock(); $target = $this->createPackageMock(); $operation = new UpdateOperation($initial, $target, 'test'); $initial ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $target ->expects($this->once()) ->method('getType') ->will($this->returnValue('library')); $installer ->expects($this->once()) ->method('supports') ->with('library') ->will($this->returnValue(true)); $installer ->expects($this->once()) ->method('update') ->with($this->repository, $initial, $target); EXCESSIVE SETUP
  • 82. use PHPUnit_Framework_TestCase as TestCase; class ParserSubjectTest extends TestCase { /** @test */ function it_notifies_subscribers() { $event = Mockery::mock("Event"); $subscriber = Mockery::mock("Subscriber"); $subscriber->shouldReceive("onChange") ->with($event); $parser = new ParserSubject(); $parser->attach($subscriber); $parser->notify($event); } } USING MOCKERY
  • 83. class ParserSubject extends PHPSpec2ObjectBehavior { /** * @param Event $event * @param Subscriber $subscriber */ function it_notifies_subscribers($event, $subscriber) { $subscriber->onChange($event)->shouldBeCalled(); $this->attach($subscriber); $this->notify($event); } } SAME EXAMPLE IN PHPSPEC
  • 84. use spies to describe indirect output expectations, retrospectively
  • 86. use PHPSpec2ObjectBehavior; class ParserSubject extends ObjectBehavior { function it_notifies_subscribers() { $event = Doubles::fromClass('Event'); $subscriber = Doubles::fromClass('Subscriber'); $this->attach($subscriber); $this->notify($event); $subscriber->spy('onChange')->callCount()->shoudBe(1); } } SPY EXAMPLE – WITH “DOUBLES” FRAMEWORK
  • 87.
  • 88. use PHPSpec2ObjectBehavior; class ParserSubject extends ObjectBehavior { /** * @param Event $event * @param Subscriber $subscriber */ function it_notifies_subscribers($event, $subscriber) { $this->attach($subscriber); $this->notify($event); $subscriber->onChange($event) ->shouldHaveBeenCalled(); } } SPY EXAMPLE – AVAILABLE WITH PROPHECY INTEGRATION
  • 89. use ProphecyProphet; class TestCase extends SomeUnitTestingFrameworkTestCase { function createDoubler($name) { $this->prophet = new ProphecyProphet; return $this->prophet->prophesize($name); } function createDummy($name) { return $this->createDoubler($name)->reveal(); } } INTEGRATING PROPHECY
  • 90. { dummy no behaviour fake control indirect output doubles stub mock messaging spy [Meszaros 2007]
  • 91. Marcello Duarte I work here I contribute here I tweet here @_md
  • 93. Questions or Comments? want to improve on testing? bit.ly/inviqa-bdd-training