dev-master
9999999-dev
MIT
The Requires
The Development Requires
by Jason McCreary
mock mockery testing
Tired of remembering the difference between mocks, partials, and spies in Mockery? I am, which is why I created double()
- a simple helper method to make using Mockery easier., (*1)
When writing tests I don't want to think about the differences between fakes, mocks, and spies. I just to create a generic test double and focus on writing my test. This generalization is common in other testing frameworks such as RSpec, td.js, and more., (*2)
To install the latest version of the double()
helper, run the command:, (*3)
composer require --dev jasonmccreary/test-double
Anytime you need to create a test double simply call double()
, (*4)
By default, double()
returns an object that will allow you to stub methods as well as verify method calls., (*5)
<?php $td = double(); $td->shouldReceive('someMethod')->andReturn(5); $td->someMethod(); // returns 5 $td->unstubbedMethod(); // returns null, does not throw an exception $td->anotherMethod(); $td->shouldHaveReceived('anotherMethod');
In Mockery, this test double is equivalent to Mockery::mock()->shouldIgnoreMissing()
or, in recent versions, Mockery::spy()
., (*6)
You can also pass double()
a reference to a class or interface. This will create a test object that extends the class or implements the interface. This allows the double to pass any type hints or type checking in your implementation., (*7)
<?php $td = double(Str::class); $td->shouldReceive('length')->andReturn(5); $td->length(); // 5 $td->substr(1, 3); // null $td instanceof Str; // true $td->shouldHaveReceived('substr')->with(1, 3);
Finally, double()
accepts a second argument of passthru. By default, passthru is false
. When set to true
, the test object will pass any method calls through to the underlying object., (*8)
In Mockery, this is equivalent to Mockery::mock(Number::class)->shouldDeferMissing()
., (*9)
<?php class Number { public function one() { return 1; } public function random() { return 5; } } $td = double(Number::class, true); $td->shouldReceive('random')->andReturn(21); $td->random(); // 21 $td->one(); // 1 $td instanceof Number; // true $td->shouldHaveReceived('one');
Note: passthru can only be used when creating a test double with a class reference as that is the only time an underlying implementation exists., (*10)
In the end, double()
is an opinionated way to create test objects for your underlying code. If it does not meet your needs, you can always create a Mockery::mock()
directly. However, doing so is likely a smell you're testing your implementation in a way that does not reflect real world behavior. Remember, double()
returns an object which implements the MockeryInterface
. So it can be treated as any other Mockery::mock()
object., (*11)
MIT
mock mockery testing