SlideShare a Scribd company logo
1 of 42
Mocking Dependencies in
PHPUnit
Matt Frost · IRC: mfrost503 · Feedback: http://joind.in/8693
We’ll be covering
✤ Defining dependencies
✤ Dependency Injection
✤ Test Doubles in Theory
✤ Test Doubles in Practice
What’s a dependency
✤ Unit Test Context
✤ A unit(s) of code that adds functionality to another unit of code
✤ Think system dependencies, but much smaller scale
Why mock them?
✤ Unit tests should cover a single unit of code in isolation
✤ A bug in a dependency makes your test a guessing game
✤ We only want to know that the code we’re testing works
Dependencies in the wild
class Auth
{
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function authenticate()
{
$username = $this->user->getUserName();
$password = $this->user->getHash();
$this->checkLogin($username,$password);
}
}
Dependency Alert!
Don’t do this!
class Auth{ public function authenticate($username, $pass){ $user = new User($username, $pass);$username = $user->getUserName();$password = $user->getHash();$this->checkLogin($username,$password);}
User cannot be
mocked
Dependency Injection
✤ Helps make code testable
✤ Helps make code flexible
✤ Constructor/Accessor methods
MOAR Dependency Injection
✤ Dependencies become properties in the object in which they’re used
✤ Paramount for mocking in unit tests!
Mocking
Defining Test Doubles
✤ Stand in for actual objects (think Stunt Doubles)
✤ Can simulate functionality from those objects
✤ Can fulfill the requirements of a type hinted method
✤ Can be used to make sure a method on the mock is called
A few more points
✤ Can’t directly mock private or protected methods
✤ Only mock what you need to test
✤ In a pinch, Reflection API can help test private/protected
Theory
✤ Unit Test shouldn’t be dependent on external data source availability
✤ Unit Test vs. Integration Test
✤ “How do I know if my query is right?”
✤ You’re testing code, not network availability
Types of Test Doubles
✤ Mock
✤ Stub
✤ Dummy
✤ Spy
Mock
✤ Verifies that a method has been called correctly
✤ Doesn’t generate a response
Anatomy of a Mock
✤ Expectation
✤ Method
✤ Parameters (if applicable)
Mock Example
public function testSetUser()
{
$user = $this->getMock('User',array('setUserId'));
$user->expects($this->once())
->method('setUserId')
->with(1);
$post = new Post($user);
$post->retrieve(10);
$post->getUserInfo();
}
Explanation
✤ Supposes $user->setUserId(1) will be called in the test
✤ Fails if $user->setUserId(1) is not called
Mock Implementation
public function getUserInfo()
{
// assume $this->data is populated from
// the $post->retrieve($id) method
$userId = $this->data['user_id'];
$this->user->setUserId($userId);
return $this->user->retrieve();
}
This is an example of code that would pass the previous test,
it’s a fictional example...so I wouldn’t use the code :)
Test Stub
✤ Ensures a method is a called correctly
✤ Generates a “fake response”
✤ Response allows for different cases to be tested
Response
Stub Example
public function testGetUserInfo()
{
$userInfo = array(
'first_name' => 'Joe',
'last_name' => 'Strummer',
'id' => 1,
'email' => 'joe.strummer@gmail.com'
);
$user = $this->getMock('User', array('retrieve'));
$user->expects($this->once())
->method('retrieve')
->will($this->returnValue($userInfo));
...
Stub Example Cont’d
...
$post = new Post($user);
$post->retrieve(10);
$information = $post->getUserInfo();
$this->assertEquals('Joe',$information['first_name']);
$this->assertEquals('Strummer',$information['last_name']);
}
Here we’re asserting that retrieve is called correctly by validating
that we get back what we expect
Dummy
✤ It’s a place holder
✤ It has no expectations or behavior
✤ It satisfies a parameter list...
Dummy Example
<?php
class Comment
{
public function __construct($comment, User $user)
{
...
}
public function validateComment()
{
//doesn't rely on User at all
}
}
Dummy Example
public function testValidateComment()
{
$user = $this->getMock('User');
$commentText = "<script></script>";
$comment = new Comment($commentText,$user);
$this->assertFalse($comment->validateComment());
}
User fulfills the method signature, but doesn’t get used
Practical Examples!
✤ External Data Sources - don’t talk to em!
✤ APIs
✤ Database Responses
Stubbing PDO
✤ Constructor is not serializable, we must adapt!
✤ PDO::prepare - returns a PDO Statement (which we can stub)
✤ We can easily cover a variety of outcomes
Constructor
<?phpclass PDOTestHelper extends PDO{ public function __construct(){}}
Overridden constructor
allows us to mock!
Setup/TearDown
public function setUp()
{
$this->pdo = $this->getMock('PDOTestHelper');
$this->statement = $this->getMock('PDOStatement');
}
public function tearDown()
{
unset($pdo);
unset($statement);
}
Stubbing a prepared statement
$this->pdo->expects($this->once())
->method('prepare')
->with($this->stringContains('SELECT * from table'))
->will($this->returnValue($this->statement))
Prepare will return a PDOStatement when executed successfully, so in
order to stub the preparation and execution of the query, this is how we
need to start.
Stubbing the execute call
$this->statement->expects($this->once())
->method('execute')
->with($this->isType('array'))
->will($this->returnValue($this->statement));
Since we’re expecting this call to succeed, we need to return the
statement again. Once we get the statement back, we’ve successfully
simulated the preparation and execution of a query!
Stubbing Fetch!
$simData = array(
‘id‘ => 1,
‘firstName‘ => ‘Lloyd’,
‘lastName‘ => ‘Christmas’,
‘occupation‘ => ‘Dog Groomer’
);
$this->statement->expects($this->once())
->method('fetch')
->will($this->returnValue($simData));
Returning Data
✤ Data Fixtures
✤ Data Providers
✤ Data should resemble what you expect to get back
Mocking API Calls
✤ Wrap it up, not just for testing for your own sanity!
✤ Once it’s wrapped it can be mocked like anything else
✤ Spies!
✤ Don’t talk to the API
Spies
✤ Helpful in making sure your method was called
✤ Or called a certain number of times
✤ Not commonly used, but I’ve found good use in testing APIs
Practical API Testing
✤ Generally, mocks suffice!
✤ If the method is transforming data, stub it!
✤ Spies are good to track multiple calls in same method
API Example
public function testGetTweets()
{
//mock example
$request = $this->getMock('Request',array('get'));
$request->expects($this->once())
->method('get')
->with('statuses');
$twitter = new Twitter($request);
$twitter->getTweets();
}
Spy Example
public function testComplicatedMethod()
{
//spy example
$request = $this->getMock('Request',array('get'));
$request->expects($this->exactly(3))
->method('get');
$twitter = new Twitter($request);
$twitter->complicatedMethod();
}
Helpful Tidbits - With()
✤ isType(String $type) - check by type
✤ stringContains($value) - string parameter
✤ contains($value) - array parameter
✤ hasArrayKey($key)
✤ greaterThan($value)
✤ isInstanceOf($className)
✤ matchesRegularExpression($pattern)
✤ equalTo($value)
Summary
✤ Injected Dependencies = Increased Testability
✤ Mock/Stub/Dummy
✤ Don’t do more than you need to!
✤ Practice makes perfect
Victory!
Mocking effectively leads to better tests and better tests lead to
better applications!
Thank you!
✤ Freenode: mfrost503
✤ Joind.in: http://joind.in/8693

More Related Content

What's hot

Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentationnicobn
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnitMindfire Solutions
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to heroJeremy Cook
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitMichelangelo van Dam
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEnterprise PHP Center
 
Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHPMarcello Duarte
 
Test in action week 2
Test in action   week 2Test in action   week 2
Test in action week 2Yi-Huan Chan
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in actionJace Ju
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Michelangelo van Dam
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013Michelangelo van Dam
 
Four Ways to add Features to Ext JS
Four Ways to add Features to Ext JSFour Ways to add Features to Ext JS
Four Ways to add Features to Ext JSShea Frederick
 
Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4Yi-Huan Chan
 

What's hot (20)

Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnit
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to hero
 
Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur PurnamaEPHPC Webinar Slides: Unit Testing by Arthur Purnama
EPHPC Webinar Slides: Unit Testing by Arthur Purnama
 
Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHP
 
Test in action week 2
Test in action   week 2Test in action   week 2
Test in action week 2
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
 
Four Ways to add Features to Ext JS
Four Ways to add Features to Ext JSFour Ways to add Features to Ext JS
Four Ways to add Features to Ext JS
 
Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4
 
Ext oo
Ext ooExt oo
Ext oo
 

Similar to Mocking Dependencies in PHPUnit

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
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
 
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
 
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 and you
PHPunit and youPHPunit and you
PHPunit and youmarkstory
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and SanityJimKellerES
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0Henrique Moody
 
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
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2eugenio pombi
 
Test in action week 3
Test in action   week 3Test in action   week 3
Test in action week 3Yi-Huan Chan
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnitferca_sl
 

Similar to Mocking Dependencies in PHPUnit (20)

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
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
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and Sanity
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0
 
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
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Test in action week 3
Test in action   week 3Test in action   week 3
Test in action week 3
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnit
 

More from mfrost503

Ain't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to AutomationAin't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to Automationmfrost503
 
Getting started-php unit
Getting started-php unitGetting started-php unit
Getting started-php unitmfrost503
 
Intro to OAuth
Intro to OAuthIntro to OAuth
Intro to OAuthmfrost503
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Changemfrost503
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Changemfrost503
 
BDD Language in PHPUnit Tests
BDD Language in PHPUnit TestsBDD Language in PHPUnit Tests
BDD Language in PHPUnit Testsmfrost503
 

More from mfrost503 (6)

Ain't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to AutomationAin't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to Automation
 
Getting started-php unit
Getting started-php unitGetting started-php unit
Getting started-php unit
 
Intro to OAuth
Intro to OAuthIntro to OAuth
Intro to OAuth
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Change
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Change
 
BDD Language in PHPUnit Tests
BDD Language in PHPUnit TestsBDD Language in PHPUnit Tests
BDD Language in PHPUnit Tests
 

Recently uploaded

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 

Recently uploaded (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 

Mocking Dependencies in PHPUnit

  • 1. Mocking Dependencies in PHPUnit Matt Frost · IRC: mfrost503 · Feedback: http://joind.in/8693
  • 2. We’ll be covering ✤ Defining dependencies ✤ Dependency Injection ✤ Test Doubles in Theory ✤ Test Doubles in Practice
  • 3. What’s a dependency ✤ Unit Test Context ✤ A unit(s) of code that adds functionality to another unit of code ✤ Think system dependencies, but much smaller scale
  • 4. Why mock them? ✤ Unit tests should cover a single unit of code in isolation ✤ A bug in a dependency makes your test a guessing game ✤ We only want to know that the code we’re testing works
  • 5. Dependencies in the wild class Auth { private $user; public function __construct(User $user) { $this->user = $user; } public function authenticate() { $username = $this->user->getUserName(); $password = $this->user->getHash(); $this->checkLogin($username,$password); } } Dependency Alert!
  • 6. Don’t do this! class Auth{ public function authenticate($username, $pass){ $user = new User($username, $pass);$username = $user->getUserName();$password = $user->getHash();$this->checkLogin($username,$password);} User cannot be mocked
  • 7. Dependency Injection ✤ Helps make code testable ✤ Helps make code flexible ✤ Constructor/Accessor methods
  • 8. MOAR Dependency Injection ✤ Dependencies become properties in the object in which they’re used ✤ Paramount for mocking in unit tests!
  • 10. Defining Test Doubles ✤ Stand in for actual objects (think Stunt Doubles) ✤ Can simulate functionality from those objects ✤ Can fulfill the requirements of a type hinted method ✤ Can be used to make sure a method on the mock is called
  • 11. A few more points ✤ Can’t directly mock private or protected methods ✤ Only mock what you need to test ✤ In a pinch, Reflection API can help test private/protected
  • 12. Theory ✤ Unit Test shouldn’t be dependent on external data source availability ✤ Unit Test vs. Integration Test ✤ “How do I know if my query is right?” ✤ You’re testing code, not network availability
  • 13. Types of Test Doubles ✤ Mock ✤ Stub ✤ Dummy ✤ Spy
  • 14. Mock ✤ Verifies that a method has been called correctly ✤ Doesn’t generate a response
  • 15. Anatomy of a Mock ✤ Expectation ✤ Method ✤ Parameters (if applicable)
  • 16. Mock Example public function testSetUser() { $user = $this->getMock('User',array('setUserId')); $user->expects($this->once()) ->method('setUserId') ->with(1); $post = new Post($user); $post->retrieve(10); $post->getUserInfo(); }
  • 17. Explanation ✤ Supposes $user->setUserId(1) will be called in the test ✤ Fails if $user->setUserId(1) is not called
  • 18. Mock Implementation public function getUserInfo() { // assume $this->data is populated from // the $post->retrieve($id) method $userId = $this->data['user_id']; $this->user->setUserId($userId); return $this->user->retrieve(); } This is an example of code that would pass the previous test, it’s a fictional example...so I wouldn’t use the code :)
  • 19. Test Stub ✤ Ensures a method is a called correctly ✤ Generates a “fake response” ✤ Response allows for different cases to be tested
  • 21. Stub Example public function testGetUserInfo() { $userInfo = array( 'first_name' => 'Joe', 'last_name' => 'Strummer', 'id' => 1, 'email' => 'joe.strummer@gmail.com' ); $user = $this->getMock('User', array('retrieve')); $user->expects($this->once()) ->method('retrieve') ->will($this->returnValue($userInfo)); ...
  • 22. Stub Example Cont’d ... $post = new Post($user); $post->retrieve(10); $information = $post->getUserInfo(); $this->assertEquals('Joe',$information['first_name']); $this->assertEquals('Strummer',$information['last_name']); } Here we’re asserting that retrieve is called correctly by validating that we get back what we expect
  • 23. Dummy ✤ It’s a place holder ✤ It has no expectations or behavior ✤ It satisfies a parameter list...
  • 24. Dummy Example <?php class Comment { public function __construct($comment, User $user) { ... } public function validateComment() { //doesn't rely on User at all } }
  • 25. Dummy Example public function testValidateComment() { $user = $this->getMock('User'); $commentText = "<script></script>"; $comment = new Comment($commentText,$user); $this->assertFalse($comment->validateComment()); } User fulfills the method signature, but doesn’t get used
  • 26. Practical Examples! ✤ External Data Sources - don’t talk to em! ✤ APIs ✤ Database Responses
  • 27. Stubbing PDO ✤ Constructor is not serializable, we must adapt! ✤ PDO::prepare - returns a PDO Statement (which we can stub) ✤ We can easily cover a variety of outcomes
  • 28. Constructor <?phpclass PDOTestHelper extends PDO{ public function __construct(){}} Overridden constructor allows us to mock!
  • 29. Setup/TearDown public function setUp() { $this->pdo = $this->getMock('PDOTestHelper'); $this->statement = $this->getMock('PDOStatement'); } public function tearDown() { unset($pdo); unset($statement); }
  • 30. Stubbing a prepared statement $this->pdo->expects($this->once()) ->method('prepare') ->with($this->stringContains('SELECT * from table')) ->will($this->returnValue($this->statement)) Prepare will return a PDOStatement when executed successfully, so in order to stub the preparation and execution of the query, this is how we need to start.
  • 31. Stubbing the execute call $this->statement->expects($this->once()) ->method('execute') ->with($this->isType('array')) ->will($this->returnValue($this->statement)); Since we’re expecting this call to succeed, we need to return the statement again. Once we get the statement back, we’ve successfully simulated the preparation and execution of a query!
  • 32. Stubbing Fetch! $simData = array( ‘id‘ => 1, ‘firstName‘ => ‘Lloyd’, ‘lastName‘ => ‘Christmas’, ‘occupation‘ => ‘Dog Groomer’ ); $this->statement->expects($this->once()) ->method('fetch') ->will($this->returnValue($simData));
  • 33. Returning Data ✤ Data Fixtures ✤ Data Providers ✤ Data should resemble what you expect to get back
  • 34. Mocking API Calls ✤ Wrap it up, not just for testing for your own sanity! ✤ Once it’s wrapped it can be mocked like anything else ✤ Spies! ✤ Don’t talk to the API
  • 35. Spies ✤ Helpful in making sure your method was called ✤ Or called a certain number of times ✤ Not commonly used, but I’ve found good use in testing APIs
  • 36. Practical API Testing ✤ Generally, mocks suffice! ✤ If the method is transforming data, stub it! ✤ Spies are good to track multiple calls in same method
  • 37. API Example public function testGetTweets() { //mock example $request = $this->getMock('Request',array('get')); $request->expects($this->once()) ->method('get') ->with('statuses'); $twitter = new Twitter($request); $twitter->getTweets(); }
  • 38. Spy Example public function testComplicatedMethod() { //spy example $request = $this->getMock('Request',array('get')); $request->expects($this->exactly(3)) ->method('get'); $twitter = new Twitter($request); $twitter->complicatedMethod(); }
  • 39. Helpful Tidbits - With() ✤ isType(String $type) - check by type ✤ stringContains($value) - string parameter ✤ contains($value) - array parameter ✤ hasArrayKey($key) ✤ greaterThan($value) ✤ isInstanceOf($className) ✤ matchesRegularExpression($pattern) ✤ equalTo($value)
  • 40. Summary ✤ Injected Dependencies = Increased Testability ✤ Mock/Stub/Dummy ✤ Don’t do more than you need to! ✤ Practice makes perfect
  • 41. Victory! Mocking effectively leads to better tests and better tests lead to better applications!
  • 42. Thank you! ✤ Freenode: mfrost503 ✤ Joind.in: http://joind.in/8693