SlideShare ist ein Scribd-Unternehmen logo
1 von 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
Dependency Alert!
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);
}
}
Don’t do this!

class Auth
{ public function authenticate($username,User cannot be
$pass)
{ $user = new User($username, $pass);
mocked
$username = $user->getHash();
= $user->getUserName();
$password
} $this->checkLogin($username,$password);
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

<?php
class 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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Object Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPObject Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPChad Gray
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにYuya Takeyama
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome TownRoss Tuck
 
R57shell
R57shellR57shell
R57shellady36
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 
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
 
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
 
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
 
Extbase and Beyond
Extbase and BeyondExtbase and Beyond
Extbase and BeyondJochen Rau
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersIan Barber
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsPierre MARTIN
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionIan Barber
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsGuilherme Blanco
 

Was ist angesagt? (20)

Presentation1
Presentation1Presentation1
Presentation1
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Object Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHPObject Calisthenics Adapted for PHP
Object Calisthenics Adapted for PHP
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
R57shell
R57shellR57shell
R57shell
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Agile database access with CakePHP 3
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
 
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
 
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
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
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
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Extbase and Beyond
Extbase and BeyondExtbase and Beyond
Extbase and Beyond
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 Version
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
 

Andere mochten auch

Slide pembelajaran
Slide pembelajaranSlide pembelajaran
Slide pembelajaranjufriati
 
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
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Changemfrost503
 
Marketing Expo - Szombati Orsi prezentációjának diái
Marketing Expo - Szombati Orsi prezentációjának diáiMarketing Expo - Szombati Orsi prezentációjának diái
Marketing Expo - Szombati Orsi prezentációjának diáiOrsolya Szombati
 
Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)
Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)
Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)Orsolya Szombati
 
Sotay sv k2_2011-2012
Sotay sv k2_2011-2012Sotay sv k2_2011-2012
Sotay sv k2_2011-2012xuan07t2
 
Slide media pembelajaran
Slide media pembelajaranSlide media pembelajaran
Slide media pembelajaranjufriati
 
Intro to OAuth
Intro to OAuthIntro to OAuth
Intro to OAuthmfrost503
 
Tugas akhir media pembelajaran
Tugas akhir media pembelajaranTugas akhir media pembelajaran
Tugas akhir media pembelajaranjufriati
 
Slide pembelajaran sosiologi
Slide pembelajaran sosiologiSlide pembelajaran sosiologi
Slide pembelajaran sosiologijufriati
 
BDD Language in PHPUnit Tests
BDD Language in PHPUnit TestsBDD Language in PHPUnit Tests
BDD Language in PHPUnit Testsmfrost503
 
Slide pembelajaran sosiologi
Slide pembelajaran sosiologiSlide pembelajaran sosiologi
Slide pembelajaran sosiologijufriati
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Changemfrost503
 
Dismissal by company initiative
Dismissal by company initiativeDismissal by company initiative
Dismissal by company initiativeOleg Starusev
 

Andere mochten auch (15)

Slide pembelajaran
Slide pembelajaranSlide pembelajaran
Slide pembelajaran
 
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
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Change
 
Marketing Expo - Szombati Orsi prezentációjának diái
Marketing Expo - Szombati Orsi prezentációjának diáiMarketing Expo - Szombati Orsi prezentációjának diái
Marketing Expo - Szombati Orsi prezentációjának diái
 
Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)
Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)
Üzletanyu Konferencia - Hogyan adj el nyomulás nélkül? (Bővített változat)
 
Sotay sv k2_2011-2012
Sotay sv k2_2011-2012Sotay sv k2_2011-2012
Sotay sv k2_2011-2012
 
Slide media pembelajaran
Slide media pembelajaranSlide media pembelajaran
Slide media pembelajaran
 
Intro to OAuth
Intro to OAuthIntro to OAuth
Intro to OAuth
 
Tugas akhir media pembelajaran
Tugas akhir media pembelajaranTugas akhir media pembelajaran
Tugas akhir media pembelajaran
 
Slide pembelajaran sosiologi
Slide pembelajaran sosiologiSlide pembelajaran sosiologi
Slide pembelajaran sosiologi
 
BDD Language in PHPUnit Tests
BDD Language in PHPUnit TestsBDD Language in PHPUnit Tests
BDD Language in PHPUnit Tests
 
Image nap prezentacio
Image nap prezentacioImage nap prezentacio
Image nap prezentacio
 
Slide pembelajaran sosiologi
Slide pembelajaran sosiologiSlide pembelajaran sosiologi
Slide pembelajaran sosiologi
 
Agent of Change
Agent of ChangeAgent of Change
Agent of Change
 
Dismissal by company initiative
Dismissal by company initiativeDismissal by company initiative
Dismissal by company initiative
 

Ähnlich wie Mocking Dependencies in PHPUnit

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and youmarkstory
 
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
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and SanityJimKellerES
 
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
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0Henrique Moody
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
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
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection apiMatthieu Aubry
 
Modernising Legacy Code
Modernising Legacy CodeModernising Legacy Code
Modernising Legacy CodeSamThePHPDev
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
Alexander Makarov "Let’s talk about code"
Alexander Makarov "Let’s talk about code"Alexander Makarov "Let’s talk about code"
Alexander Makarov "Let’s talk about code"Fwdays
 

Ähnlich wie Mocking Dependencies in PHPUnit (20)

Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
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
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Coding for Scale and Sanity
Coding for Scale and SanityCoding for Scale and Sanity
Coding for Scale and Sanity
 
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
 
TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0TestFest - Respect\Validation 1.0
TestFest - Respect\Validation 1.0
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Test in action week 3
Test in action   week 3Test in action   week 3
Test in action week 3
 
Workshop unittesting
Workshop unittestingWorkshop unittesting
Workshop unittesting
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
 
Modernising Legacy Code
Modernising Legacy CodeModernising Legacy Code
Modernising Legacy Code
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Alexander Makarov "Let’s talk about code"
Alexander Makarov "Let’s talk about code"Alexander Makarov "Let’s talk about code"
Alexander Makarov "Let’s talk about code"
 

Kürzlich hochgeladen

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
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
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 

Kürzlich hochgeladen (20)

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
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
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 

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 Dependency Alert! 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); } }
  • 6. Don’t do this! class Auth { public function authenticate($username,User cannot be $pass) { $user = new User($username, $pass); mocked $username = $user->getHash(); = $user->getUserName(); $password } $this->checkLogin($username,$password);
  • 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 <?php class 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!