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:
Authorizer class implements the
now we want to test
loginCount method of
System class requires an instance of
AuthorizerInterface to create a
System instance, so instead of using a real
Authorizer we can use a
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
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:
- 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.
- 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
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!