Over a million developers have joined DZone.

Practical PHP Testing Patterns: Dummy Object

DZone's Guide to

Practical PHP Testing Patterns: Dummy Object

· Web Dev Zone
Free Resource

Never build auth again! Okta makes it simple to implement authentication, authorization, MFA and more in minutes. Try the free developer API today! 

A Dummy Object is the simplest specialization of the Test Double pattern. As always, if you want to avoid constructing the real collaborator of the System Under Test, use a Test Double: you'll get a shorter and simpler test, with the plus of isolation from other concrete classes.

When no methods are called on a Test Double, nor fields are accessed, the Dummy Object is the ideal specialization. Usually this kind of object is only passed around to satisfy type hints and null checks. Also checks may be made on its equality or identicalness in the internals of other Test Doubles (Mocks or Stubs) where it is passed as a parameter or returned.

Thus a really short definition of a Dummy Object is a Test Double whose only utility is being passed around as a method parameter (this comprehends also constructor parameters that must be filled in.) Note also that Dummy values can be used in PHP, where not everything is an object. You may substitute collaborators even with strings.


The easiest way to implement a Dummy Object is to pass null instead of the real object. If there is a type hint, this method requires an = null clause that sets null as the default value (this is different from Java semantics where you can always pass null if there are no explicit checks.)

I use this trick on constructors sometimes: they are only called in a Factory anyway, so making their parameters optional is not dangeours. But on methods it's not feasible to add defaults as we like, as it disfigures the Api. Moreover, you can't do equality checks on null: all null values are the same (just like electrons).

Languages even more dynamic than PHP remove the possibility of type hints (which mimics static types) and allow everything to be passed in, as long as you don't call a not existent method. In PHP, it's not really an hint: you must pass an instance of that type for the method to avoid explosion.

A simple subclass (or interface implementation) can do the job, and you can define it in the same source file as the test, in order to instantiate an object inline. In this case, namespaces (as manual prefixes or the PHP 5.3 ones) may help in avoiding conflicts.

A final possibility is of leveraging PHPUnit support with getMock(). For PHPUnit everything is a mock: however, this method can generate also Dummy Objects.
In case you're substituting concrete classes, overriding the constructor may be necessary: in this case, my getMockBuilder() Api may help you.

One advantage of PHPUnit magic generation is that it's possible to add expectations on Dummy Objects, and test that an method is not invoked by raising an error in case of a call. The $this->never() matcher serves this purpose, but you should set it on all methods. It may be an superfluos check, but if the production code really calls a method on a Dummy built in this way, null will be returned silently.


  • A Dummy Argument is provided as a method parameter during a call, either directly in the test code or indirectly in the production code which we exercise.
  • A Dummy Attribute instead is an attribute (aka field) populated with a Test Double to avoid complex construction. For the purpose of the current test, the contents of these fields may be ignored: for example, in the exercised methods there is no mention of them.


The sample code shows you how to create a Dummy Object in every possible way I know.

class DummyObjectTest extends PHPUnit_Framework_TestCase
     * The Test Method names describe the different ways to produce
     * a Dummy Object (or just a Dummy value).
    public function testNullOrStringsCanBeUsedAsADummyIfThereAreNoTypeHints()
        $sut = new MostDynamicSut(null);
        $sut = new MostDynamicSut('this should not be called');

    public function testNullCanBeUsedAsADummyIfItsTheDefaultForTypeHint()
        // I prefer an explicit parameter; also there may be other parameters after that
        $sut = new TypeHintedWithDefaultSut(null);

    public function testAnInlineClassCanBeUsedToInstantiateADummyObject()
        $sut = new FullyDefensiveSut(new DummyIterator);

    public function testADynamicallyGeneratedDummyObjectCanBeBuiltByPHPUnit()
        $dummy = $this->getMock('Iterator');
        $sut = new FullyDefensiveSut($dummy);

    public function testPHPUnitCanOverrideTheConstructorOfADummy()
        $dummy = $this->getMockBuilder('ArrayIterator')
        $sut = new FullyDefensiveSut($dummy);

    public function testPHPUnitCanCheckThatTheDummyMethodsAreNeverCalled()
     // often if someone calls it, lack of return value (null) causes explosion anyway.but if it's a void...
        $dummy = $this->getMock('Iterator');
        $sut = new FullyDefensiveSut($dummy);

class MostDynamicSut
    public function __construct($iterator) { }

class TypeHintedWithDefaultSut
    public function __construct(Iterator $iterator = null) { }

class FullyDefensiveSut
    public function __construct(Iterator $iterator) { }

class DummyIterator extends ArrayIterator
    public function __construct() {}



This was the last pattern of the Practical PHP Testing Patterns series. Thanks for your attention during the journey: we got through the whole list of xUnit patterns and their application to PHP code.

If you're already missing this bi-weekly articles, don't worry: a new series is about to start...

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!


Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}