Stub you!Andrea Giuliano@bit_sharkmercoledì 26 giugno 13
When you’re doing testingyou’re focusing on one element at a timeUnit testingmercoledì 26 giugno 13
to make a single unit workyou often need other unitsThe problem ismercoledì 26 giugno 13
provide canned answers to calls made during thetest, usually not responding at all to anythingoutside whats programmed in ...
objects pre-programmed with expectationswhich form a specification of the callsthey are expected to receiveMock objectsmerc...
Mock objectsBehaviourverificationStateverificationStub objectsmercoledì 26 giugno 13
A simple stub examplepublic interface MailService {public function send(Message $msg);}public class MailServiceStub implem...
A simple stub examplestate verificationclass OrderStateTester{...public function testOrderSendsMailIfFilled() {$order = new...
We’ve wrote a simple test.We’ve tested only one message has been sentBUTWe’ve not tested it was sent to the rightperson wi...
...using mock objectclass OrderInteractionTester...public function testOrderSendsMailIfFilled() {$order = new Order(TALISK...
PHAKEPHP MOCKING FRAMEWORKmercoledì 26 giugno 13
Zero-configPhake was designed with PHPUnit in mindmercoledì 26 giugno 13
stub a method$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->with(param)->will...
stub a method$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->with(param)->will...
an exampleclass ShoppingCartTest extends PHPUnit_Framework_TestCase{! private $shoppingCart;! private $item1;! private $it...
ShoppingCart implementationclass ShoppingCart{! /**! * Returns the current sub total of the customers order! * @return mon...
stubbing multiple calls$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->will($t...
stubbing multiple calls$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->will($t...
an exampleclass ItemGroupTest extends PHPUnit_Framework_TestCase{! private $itemGroup;! private $item1;! private $item2;! ...
an example with consecutive callsclass ItemGroupTest extends PHPUnit_Framework_TestCase{! private $itemGroup;! private $it...
partial mockclass MyClass{! private $value;! public __construct($value)! {! ! $this->value = $value;! }! public function f...
partial mockclass MyClass{! private $value;! public __construct($value)! {! ! $this->value = $value;! }! public function f...
default stubclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testDefaultStubs()! {! ! $mock = Phake:...
stubbing magic methodsclass MagicClass{public function __call($method, $args){return __call;}}mercoledì 26 giugno 13
stubbing magic methodsclass MagicClass{public function __call($method, $args){return __call;}}class MagicClassTest extends...
verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = $this->getMock...
verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = $this->getMock...
verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = $this->getMock...
verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = Phake::mock(Ph...
verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = Phake::mock(Ph...
verify invocations in orderclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = Phake...
verify no interactionclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitNoInteraction(){$mock = $t...
verify no interactionclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitNoInteraction(){$mock = $t...
verify magic callsclass MagicClass{public function __call($method, $args){return __call;}}mercoledì 26 giugno 13
verify magic callsclass MagicClass{public function __call($method, $args){return __call;}}class MagicClassTest extends PHP...
throwing exceptionclass MyClass{! private $logger;!! public function __construct(Logger $logger)! {! ! $this->logger = $lo...
throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions...
throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions...
throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions...
throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions...
parameter capturinginterface CardCollection{public function getNumberOfCards();}class MyPokerGameTest extends PHPUnit_Fram...
Phakepear channel-discover pear.digitalsandwich.compear install digitalsandwich/PhakeAvailable via pearAvailable via Compo...
Questions?Thanks!Andrea Giuliano@bit_sharkmercoledì 26 giugno 13
Upcoming SlideShare
Loading in …5
×

Stub you!

705
-1

Published on

Phake mocking object presentation to PUG Rome

Published in: Technology, Education
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
705
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
9
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Stub you!

  1. 1. Stub you!Andrea Giuliano@bit_sharkmercoledì 26 giugno 13
  2. 2. When you’re doing testingyou’re focusing on one element at a timeUnit testingmercoledì 26 giugno 13
  3. 3. to make a single unit workyou often need other unitsThe problem ismercoledì 26 giugno 13
  4. 4. provide canned answers to calls made during thetest, usually not responding at all to anythingoutside whats programmed in for the testStub objectsmercoledì 26 giugno 13
  5. 5. objects pre-programmed with expectationswhich form a specification of the callsthey are expected to receiveMock objectsmercoledì 26 giugno 13
  6. 6. Mock objectsBehaviourverificationStateverificationStub objectsmercoledì 26 giugno 13
  7. 7. A simple stub examplepublic interface MailService {public function send(Message $msg);}public class MailServiceStub implements MailService {private $sent = 0;public function send(Message $msg) {/*I’m just sent the message */++$sent;}public function numberSent() {return $this->sent;}}implementationmercoledì 26 giugno 13
  8. 8. A simple stub examplestate verificationclass OrderStateTester{...public function testOrderSendsMailIfFilled() {$order = new Order(TALISKER, 51);$mailer = new MailServiceStub();$order->setMailer($mailer);$order->fill(/*somestuff*/);$this->assertEquals(1, $mailer->numberSent());}}mercoledì 26 giugno 13
  9. 9. We’ve wrote a simple test.We’ve tested only one message has been sentBUTWe’ve not tested it was sent to the rightperson with right content etc.mercoledì 26 giugno 13
  10. 10. ...using mock objectclass OrderInteractionTester...public function testOrderSendsMailIfFilled() {$order = new Order(TALISKER, 51);$warehouse = $this->mock(“Warehouse”);$mailer = $this->mock(“MailService”);$order->setMailer($mailer);$mailer->expects(once())->method("send");$warehouse->expects(once())->method("hasInventory")->withAnyArguments()->will(returnValue(false));$order->fill($warehouse->proxy());}}mercoledì 26 giugno 13
  11. 11. PHAKEPHP MOCKING FRAMEWORKmercoledì 26 giugno 13
  12. 12. Zero-configPhake was designed with PHPUnit in mindmercoledì 26 giugno 13
  13. 13. stub a method$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->with(param)->will($this->returnValue(returned));with PHPUnitmercoledì 26 giugno 13
  14. 14. stub a method$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->with(param)->will($this->returnValue(returned));$stub = Phake::mock(NamespaceMyClass);Phake::when($stub)->doSomething(param)->thenReturn(returned);with PHPUnitwith Phakemercoledì 26 giugno 13
  15. 15. an exampleclass ShoppingCartTest extends PHPUnit_Framework_TestCase{! private $shoppingCart;! private $item1;! private $item2;! private $item3;! public function setUp()! {! ! $this->item1 = Phake::mock(Item);! ! $this->item2 = Phake::mock(Item);! ! $this->item3 = Phake::mock(Item);! ! Phake::when($this->item1)->getPrice()->thenReturn(100);! ! Phake::when($this->item2)->getPrice()->thenReturn(200);! ! Phake::when($this->item3)->getPrice()->thenReturn(300);! ! $this->shoppingCart = new ShoppingCart();! ! $this->shoppingCart->addItem($this->item1);! ! $this->shoppingCart->addItem($this->item2);! ! $this->shoppingCart->addItem($this->item3);! }! public function testGetSub()! {! ! $this->assertEquals(600, $this->shoppingCart->getSubTotal());! }}mercoledì 26 giugno 13
  16. 16. ShoppingCart implementationclass ShoppingCart{! /**! * Returns the current sub total of the customers order! * @return money! */! public function getSubTotal()! {! ! $total = 0;! ! foreach ($this->items as $item)! ! {! ! ! $total += $item->getPrice();! ! }! ! return $total;! }}mercoledì 26 giugno 13
  17. 17. stubbing multiple calls$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->will($this->returnCallback(function($param) {$toReturn = array(param1 => returned1,param2 => returned2,}));with PHPUnitmercoledì 26 giugno 13
  18. 18. stubbing multiple calls$stub = $this->getMock(NamespaceMyClass);$stub->expects($this->any())->method(doSomething)->will($this->returnCallback(function($param) {$toReturn = array(param1 => returned1,param2 => returned2,}));$stub = Phake::mock(NamespaceMyClass);Phake::when($stub)->doSomething(param1)->thenReturn(returned1)Phake::when($stub)->doSomething(param2)->thenReturn(returned2);with PHPUnitwith Phakemercoledì 26 giugno 13
  19. 19. an exampleclass ItemGroupTest extends PHPUnit_Framework_TestCase{! private $itemGroup;! private $item1;! private $item2;! private $item3;! public function setUp()! {! ! $this->item1 = Phake::mock(Item);! ! $this->item2 = Phake::mock(Item);! ! $this->item3 = Phake::mock(Item);! ! $this->itemGroup = new ItemGroup(array($this->item1, $this->item2, $this->item3));! }! public function testAddItemsToCart()! {! ! $cart = Phake::mock(ShoppingCart);! ! Phake::when($cart)->addItem($this->item1)->thenReturn(10);! ! Phake::when($cart)->addItem($this->item2)->thenReturn(20);! ! Phake::when($cart)->addItem($this->item3)->thenReturn(30);! ! $totalCost = $this->itemGroup->addItemsToCart($cart);! ! $this->assertEquals(60, $totalCost);! }}mercoledì 26 giugno 13
  20. 20. an example with consecutive callsclass ItemGroupTest extends PHPUnit_Framework_TestCase{! private $itemGroup;! private $item1;! private $item2;! private $item3;! public function setUp()! {! ! $this->item1 = Phake::mock(Item);! ! $this->item2 = Phake::mock(Item);! ! $this->item3 = Phake::mock(Item);! ! $this->itemGroup = new ItemGroup(array($this->item1, $this->item2, $this->item3));! }! public function testAddItemsToCart()! {! ! $cart = Phake::mock(ShoppingCart);! ! Phake::when($cart)->addItem(Phake::anyParameters())->thenReturn(10)! ! ! ->thenReturn(20)! ! ! ->thenReturn(30);! ! $totalCost = $this->itemGroup->addItemsToCart($cart);! ! $this->assertEquals(30, $totalCost);! }}mercoledì 26 giugno 13
  21. 21. partial mockclass MyClass{! private $value;! public __construct($value)! {! ! $this->value = $value;! }! public function foo()! {! ! return $this->value;! }}mercoledì 26 giugno 13
  22. 22. partial mockclass MyClass{! private $value;! public __construct($value)! {! ! $this->value = $value;! }! public function foo()! {! ! return $this->value;! }}class MyClassTest extends PHPUnit_Framework_TestCase{! public function testCallingParent()! {! ! $mock = Phake::partialMock(MyClass, 42);! ! $this->assertEquals(42, $mock->foo());! }}mercoledì 26 giugno 13
  23. 23. default stubclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testDefaultStubs()! {! ! $mock = Phake::mock(MyClass, Phake::ifUnstubbed()->thenReturn(42));! ! $this->assertEquals(42, $mock->foo());! }}class MyClass{! private $value;! public __construct($value)! {! ! $this->value = $value;! }! public function foo()! {! ! return $this->value;! }}mercoledì 26 giugno 13
  24. 24. stubbing magic methodsclass MagicClass{public function __call($method, $args){return __call;}}mercoledì 26 giugno 13
  25. 25. stubbing magic methodsclass MagicClass{public function __call($method, $args){return __call;}}class MagicClassTest extends PHPUnit_Framework_TestCase{public function testMagicCall(){$mock = Phake::mock(MagicClass);Phake::when($mock)->myMethod()->thenReturn(42);$this->assertEquals(42, $mock->myMethod());}}MyMethod is handled by __call() methodmercoledì 26 giugno 13
  26. 26. verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = $this->getMock(PhakeTest_MockedClass);$mock->expects($this->once())->method(fooWithArgument)->with(foo);$mock->expects($this->once())->method(fooWithArgument)->with(bar);$mock->fooWithArgument(foo);$mock->fooWithArgument(bar);}}with PHPUnit - BAD!mercoledì 26 giugno 13
  27. 27. verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = $this->getMock(PhakeTest_MockedClass);$mock->expects($this->once())->method(fooWithArgument)->with(foo);$mock->expects($this->once())->method(fooWithArgument)->with(bar);$mock->fooWithArgument(foo);$mock->fooWithArgument(bar);}}with PHPUnit - BAD!//I’m failing, with you!mercoledì 26 giugno 13
  28. 28. verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = $this->getMock(PhakeTest_MockedClass);$mock->expects($this->at(0))->method(fooWithArgument)->with(foo);$mock->expects($this->at(1))->method(fooWithArgument)->with(bar);$mock->fooWithArgument(foo);$mock->fooWithArgument(bar);}}with PHPUnit - BETTERmercoledì 26 giugno 13
  29. 29. verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = Phake::mock(PhakeTest_MockedClass);$mock->fooWithArgument(foo);$mock->fooWithArgument(bar);Phake::verify($mock)->fooWithArgument(foo);Phake::verify($mock)->fooWithArgument(bar);}}with Phakemercoledì 26 giugno 13
  30. 30. verify invocationsclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = Phake::mock(PhakeTest_MockedClass);$mock->fooWithArgument(foo);$mock->fooWithArgument(foo);Phake::verify($mock, Phake::times(2))->fooWithArgument(foo);}}with Phake - multiple invocationPhake::times($n)Phake::atLeast($n)Phake::atMost($n)options:mercoledì 26 giugno 13
  31. 31. verify invocations in orderclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitMock(){$mock = Phake::mock(PhakeTest_MockedClass);$mock->fooWithArgument(foo);$mock->fooWithArgument(bar);Phake::inOrder(Phake::verify($mock)->fooWithArgument(foo),Phake::verify($mock)->fooWithArgument(bar));}}mercoledì 26 giugno 13
  32. 32. verify no interactionclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitNoInteraction(){$mock = $this->getMock(PhakeTestCase_MockedClass);$mock->expects($this->never())->method(foo);//....}}with PHPUnitmercoledì 26 giugno 13
  33. 33. verify no interactionclass MyTest extends PHPUnit_Framework_TestCase{public function testPHPUnitNoInteraction(){$mock = $this->getMock(PhakeTestCase_MockedClass);$mock->expects($this->never())->method(foo);//....}}with PHPUnitclass MyTest extends PHPUnit_Framework_TestCase{public function testPhakeNoInteraction(){$mock = Phake::mock(PhakeTestCase_MockedClass);//...Phake::verifyNoInteractions($mock);}}with Phakemercoledì 26 giugno 13
  34. 34. verify magic callsclass MagicClass{public function __call($method, $args){return __call;}}mercoledì 26 giugno 13
  35. 35. verify magic callsclass MagicClass{public function __call($method, $args){return __call;}}class MagicClassTest extends PHPUnit_Framework_TestCase{public function testMagicCall(){$mock = Phake::mock(MagicClass);$mock->myMethod();Phake::verify($mock)->myMethod();}}mercoledì 26 giugno 13
  36. 36. throwing exceptionclass MyClass{! private $logger;!! public function __construct(Logger $logger)! {! ! $this->logger = $logger;! }! public function processSomeData(MyDataProcessor $processor, MyData $data)! {! ! try {! ! ! $processor->process($data);! ! }! ! catch (Exception $e) {! ! ! $this->logger->log($e->getMessage());! ! }! }}Suppose you have a class that logs a message with the exception messagemercoledì 26 giugno 13
  37. 37. throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions()! {! ! $logger = Phake::mock(Logger);! ! $data = Phake::mock(MyData);! ! $processor = Phake::mock(MyDataProcessor);! !Suppose you have a class that logs a message with the exception messagemercoledì 26 giugno 13
  38. 38. throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions()! {! ! $logger = Phake::mock(Logger);! ! $data = Phake::mock(MyData);! ! $processor = Phake::mock(MyDataProcessor);! !Suppose you have a class that logs a message with the exception message! ! Phake::when($processor)->process($data)->thenThrow(new Exception(My error message!);mercoledì 26 giugno 13
  39. 39. throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions()! {! ! $logger = Phake::mock(Logger);! ! $data = Phake::mock(MyData);! ! $processor = Phake::mock(MyDataProcessor);! !Suppose you have a class that logs a message with the exception message! ! Phake::when($processor)->process($data)->thenThrow(new Exception(My error message!);! ! $sut = new MyClass($logger);! ! $sut->processSomeData($processor, $data);mercoledì 26 giugno 13
  40. 40. throwing exceptionclass MyClassTest extends PHPUnit_Framework_TestCase{! public function testProcessSomeDataLogsExceptions()! {! ! $logger = Phake::mock(Logger);! ! $data = Phake::mock(MyData);! ! $processor = Phake::mock(MyDataProcessor);! !Suppose you have a class that logs a message with the exception message! ! Phake::when($processor)->process($data)->thenThrow(new Exception(My error message!);! ! $sut = new MyClass($logger);! ! $sut->processSomeData($processor, $data);! ! Phake::verify($logger)->log(My error message!);! }}mercoledì 26 giugno 13
  41. 41. parameter capturinginterface CardCollection{public function getNumberOfCards();}class MyPokerGameTest extends PHPUnit_Framework_TestCase{public function testDealCards(){$dealer = Phake::partialMock(MyPokerDealer);$players = Phake::mock(PlayerCollection);$cardGame = new MyPokerGame($dealer, $players);Phake::verify($dealer)->deal(Phake::capture($deck), $players);$this->assertEquals(52, $deck->getNumberOfCards());}}Class MyPokerDealer{public function getNumberOfCards(){....$dealer->deal($deck, $players)}}mercoledì 26 giugno 13
  42. 42. Phakepear channel-discover pear.digitalsandwich.compear install digitalsandwich/PhakeAvailable via pearAvailable via Composer"phake/phake": "dev-master"mercoledì 26 giugno 13
  43. 43. Questions?Thanks!Andrea Giuliano@bit_sharkmercoledì 26 giugno 13
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×