Mocking in PHPUnit

A practical guide to mocking in PHPUnit

Richard Miles
Aug 19, 2019 · 4 min read

First, what is a mock?

A mock is a piece of dummy code that helps your tests run in a way that isolates specific functionality.

e.g. we can mock out a function to return values in a way that makes a related piece of functionality either pass or fail a test.

An example of a mocked function would be a mimicked response from a database call with dummy data that matches what we would expect the database call returned data to look like.

This is useful in unit testing as we don’t actually want to call a database, but rather test a specific piece of functionality that would interact with an expected response from a database.

When should we use mocking?

For starters, some common elements that you might want to mock include:

  • Database queries
  • 3rd party libraries
  • http requests
  • Anything tightly coupled with the underlying hardware of the operating system (e.g. Date time related or reading and writing to a file on disk)
  • Functions with unpredictable results (random numbers)

The common thread here is that we don’t necessarily want to test anything that is outside of the scope of the individual functions we write. However, it’s worth mentioning that sometimes you do want to test code that has been integrated with one of these “external” services, making sure that it does in fact work as expected. This falls into the realm of an integration test. An integration test is basically asserting that multiple key components work together as expected, e.g. your code works as expected using actual database calls.

Here I have chosen to focus specifically on unit testing, which follows on from this intro to assert with PHP Unit — focusing on testing a single “unit” of functionality.

Jumping into the code

For our example I am going to create a “person” class that can do specific person related things, one of those things is display the greeting message “Hello World”.

Good stuff, so now we can create a new person and tell them to greet the world.

We can easily transform this into a basic test assertion:

Now I want to be able to query a list of users from a database and depending on the ID passed into my greeting function, return the corresponding name of that person in the database.

The database class would probably look something like this:

We can now pull this into our person class and use it:

We don’t actually want to test that getPersonByID returns a result from our database, but instead that person->greeting(2) gives us a result that we expect.

In theory, our test code would look like this (NB: this is an example of bad code):

To avoid actually making a database query we can mock our database class within our test.

Let’s go through this one section at a time to see what’s going on:

Firstly we want to build a mock of the Database class that is exactly the same except we are telling the MockBuilder that we are going to get setting the getPersonByID later on ourselves.

$dbMock now becomes our $db

Next we create a “fake” person object returned from the db that is just a standard class type with a name attribute of “Bob”:

Next we tell the newly created mock class to return our “fake” person whenever the getPersonByID function is called, instead of calling the real function that exists on the Database class:

Next we pass our mocked Database instance into our Person constructor as opposed to a real one:

Finally we call our greeting function which will in turn call our mocked Database instance during its execution.

Mocking out unrelated or external functionality is a great way to isolate only the code that you want to test.

The above example is quite simple in nature, and mocking can become complicated as a project grows. It takes a fair amount of intuition to learn the best way to implement mocking when writing tests, but this will become easier the more you practice.

I would be keen to hear any other thoughts or answer any questions you may have on the subject in the comments below.


We build beautiful front ends on scalable, well-engineered…

Richard Miles

Written by

Full-stack Developer



We build beautiful front ends on scalable, well-engineered back ends to produce software products your users will love. Get in touch:

More From Medium

More from NONA

More from NONA

More from NONA

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade