Test doubles: Dummy, Stub, Spy, Mock

Today I am going to write about Test doubles! Its always confusing when to use stub or mock. Lets first define different kind of test doubles.

N.B. I am taking examples from Uncle Bob’s Little Mocker but translating it into PHP way.


Dummies are used in tests when we need to provide an instance as an argument to create an instance of SUT (System Under Test) but its never going to be used in the test.

Suppose we have an interface Authorizer that has a method authorize as follows:

and an Authorizer class implements the Authorizerinterface

now we want to test loginCount method of System class:

It seems System class requires an instance of AuthorizerInterface to create a System instance, so instead of using a real Authorizer we can use a DummyAuthorizer here.

so in the test method we can use it as follows:

if we look carefully into the test, we only want to test the loginCount method and it does not matter how the System instance was created as long as we are providing an instance of AuthorizerInterface.


Say we want to test a SUT method that internally make a call to DOC method but and we dont care what it does but to return a specific value, we need to create a stub.

Here is an example

other scenario would be:

  1. The test method is doing an HTTP API call but we dont actually need to any real call, we can stub it out and return a custom response.
  2. We want to test a part of a system that requires a logged in user, create a user stub and return true for that particular method.


Use Spy for spying, say you stub a method how do we know that stubbed method was actually get called in the test ?

Here is a an example

So at the end of the test we can assert if $authorized_was_called is true. We can do a lot more in Spy, we can check the arguments, how many times it get called and so on.


Now lets talk about Mock! finally! If we look carefully in the Spy we were asserting something that is not a SUT thing but a DOC thing, by accessing it outside the Spy class we are tight coupling it with the tests which makes it vulnerable, what if we move the assertion inside the Spy ? you got it, thats how we create a Mock and thats why we have Mocking frameworks like Phake or Mockery


Testing with some real objects or modules that are not going to be used in production, example SQLite db would be preferable for tests that a MySQL db. Keep in mind that Fake has real business behavior, as Uncle bob said

Mock is a kind of spy, a spy is a kind of stub, and a stub is a kind of dummy. But a fake isn’t a kind of any of them. It’s a completely different kind of test double.

Hope this will remove some of the confusion about Test doubles!