Skip to main content

The Difference Between a Mock and a Stub

Context of Modeling Assumptions
As you may recall, a unit test is sequence of instructions to run an automated test against an isolated unit of software code. A unit test may be considered to have these three phases:
  1. Modeling the assumptions
  2. Exercising the unit of code
  3. Verifying the acceptance criteria
Aside: This fits in nicely with the scrum agile framework, because a developer could theoretically develop one unit test for each user story. Each user story should already include concise details for assumptions and acceptance criteria.
It is particularly critical to model the assumptions before exercising the unit of code. The assumptions are the details of external factors that influence a unit's operation. It is important to call out the external assumptions to keep those distinct from the functionality of the unit itself. If a developer tries to write a unit test without modeling the assumptions, when they attempt to exercise the unit of code, they will also be exercising other code outside the unit. In that case, it is no longer a true unit test.

Importance of Calling Out Assumptions
For example: let's say we have the following user story: (I simplified this story for the purpose of this example leaving off elements which should be included in stories such as priority, points, and tasks)
  • Story: As a responsible parent, I want pictures of what is on my child's display, So that I can be aware of how they are using their device
    (See Snap Screen™ for a real Serafino Software™ product that is not the same but somewhat similar to this)
  • Assumptions:
    • Given the software is running on the child's device, When it requests a picture of what is on the display from the device environment, Then it will receive one
    • Given the software is running, When it requests to send a picture to the parent through the cloud provider, Then the picture will be sent to the cloud provider
  • Acceptance Criteria:
    • Given the software is running on the child's device, When it is 2:00 PM, Then it will request a picture of what is on the display from the runtime environment
    • Given the software is setup, When it receives a picture of the display, Then it will request the cloud provider to send the picture to the parent
Aside: Notice it can be helpful to write scrum user stories in the format:
As a [persona], I want [feature], So that [business value].

And it is helpful to write acceptance criteria in the format:
Given [precondition(s)], When [condition], Then [expected result].
Notice: The device environment that takes a picture of what is on the display, and the cloud provider that sends the picture to the parent, are external to the code in this actual unit. Therefore, that functionality should be called out as assumptions, and not excluded from being exercised by the isolated unit test. The code to implement those features should already be covered by its own testing. We could have an "end to end" test that included testing external functionality, but then it wouldn't be a unit test, it would be system test.

That is why we need to model the assumptions about the functionality of code external to the unit. The need to model these assumptions is the reason for the introduction of mocks or stubs.
We could have an "end to end" test that included testing external functionality, but then it wouldn't be a unit test, it would be system test.
Mocks and Stubs
Two main ways to model assumptions are called mocks and stubs. I have heard some developers make the mistake of using these terms interchangeably. I don't blame them, because in the past I have been unsure about the difference myself.

Stubs: Stubs could also be called fakes or dummies but as a former coworker once pointed out, such terminology is not necessarily the most excellent to inspire confidence in the uninitiated who overhear such terms. Therefore, I prefer the term, stubs. A stub is simply a piece of code that provides a model of an external assumption for a unit test. In other words, when a developer writes a piece of code to model an assumption for a unit test, he can consider that piece of code to be a stub.
A stub is simply a piece of code that provides a model of an external assumption for a unit test.
Returning to our example user story, we might write the following unit test (this is pseudo-code):
  • "Stub Device Environment":
    • When asked, return a "Stub Picture of the Display"
  • "Stub Cloud Service":
    • When asked, simulate sending a picture to the parent by recording the picture that has been requested to be sent
  • Use dependency injection to inject the stub device environment and stub cloud service into the unit
  • Exercise the unit
  • Verify that the stub cloud service has simulated sending the stub picture of the display by verifying it has recorded that the stub picture has been requested to be sent
Using stubs like this works fine for modeling a few big complicated external assumptions. And, sometimes it is still more feasible to use stubs in some cases. However, it takes much manual coding, and, especially when there are a lot of assumptions, it can be much more efficient to use mocks.

Mocks: Mocks are basically a way to automate the creation of stubs. Before the technology came along for mocking dependencies, it was hard work to manually create stubs to stub out all of the dependencies. Mocking frameworks provide mocks, which include the ability to record mock results to return for certain conditions, and the ability to verify that the mocks were exercised as expected. For example, we could improve our earlier test like this:
  • Create a "Mock Device Environment," which, when asked, returns a "Stub Picture of the Display"
  • Create a "Mock Cloud Service," (which can be asked to send a picture to the parent)
  • Use dependency injection to inject the mock device environment and mock cloud service into the unit
  • Exercise the unit
  • Verify that the mock cloud service has been requested to send the stub picture of the display to the parent
Notice that a picture of the display is simply data, so it does not make sense to try to replace the stub picture with a mock picture. For data such as pictures, we should still use stubs. For functionality, on the other hand, mocks improve coding efficiency and the elegance and quality of the resulting test code, because they automate the process of recording conditions, returning mock results, and verifying calls.
Mocking frameworks provide mocks, which include the ability to record mock results to return for certain conditions, and the ability to verify that the mocks were exercised as expected.
We can definitely see that mocks and stubs are not the same thing. They are quite different.

Popular posts from this blog

What We're About

About UsMission Statement: We provide a product to make high performing software developers happy by giving them a chance to work in a more self-directed way on software that is more meaningful to them. Core Values (in priority order):Integrity: Honesty, trustworthiness, and faithfulnessPreparation: Research, planning, and goalsReputation: Branding, naming, presence, and networkingProfitability: Product salesProduction: Product development, ideas, online contentImprovement: Research and trainingSupport: Minimal overhead Who We Are
Isaac Serafino is a Software Architect in Omaha, Nebraska. He has a strong experience developing technology solutions. He has long had the dream to lead his own startup business.
Our ProductsSnap Screen™
More efficiently provide a safe environment for using electronic devices. Sends pictures of what is on the display at somewhat random times so user knows they could be observed at any time, but the supervisor does not need to be their watching over their sho…

The Invasion of the Developer Commandos™

I. Why Deploy Commandos? It's hard to find the best people to solve difficult problems. By deploying Developer Commandos™, you can get great software developed without needing to figure out how to find the software developers. II. What are Developer Commandos? Unlike an old fashioned developer, a commando works independently. They manage themselves so you won't need to. III. How Can You Deploy Commandos? A. Create a Project Use a project host like GitHub to create a shared workspace online. Commandos will be able to contribute to your software project through this workspace. B. Obtain Incentives Use a cryptocurrency exchange like Coinbase to purchase an amount of a cryptocurrency such as Ether. You will be able to use this cryptocurrency to provide an incentive for commandos. C. Post Opportunities Use a bounty network such as Gitcoin to post bounties. A bounty describes the software problem you need resolved, and allows you to attach a cryptocurrency incentive for resolving i…