What's the difference between faking, mocking, and stubbing?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
In software development, particularly in the realm of testing, the terms "faking," "mocking," and "stubbing" refer to different types of test doubles. These are simplified versions of complex real objects used during testing. Each type has particular roles and is chosen based on what aspect of the system is being tested. Here we will explore the differences among these three and when to use each type in unit testing.
Mocking
Definition: Mocking is a technique used to isolate behavior for testing, where you simulate the behavior of complex, real (and often external) systems. A mock object will mimic the interactions that a real component would have, but provides the ability to precisely control its behavior. It's especially useful when the real components are impractical to incorporate into a test.
Example and Usage: Suppose you're testing an application that interacts with a remote third-party billing API. Instead of calling the real API (which is slow and has cost implications), you could use a mocked object that mimics the API. This mock could be programmed to return predefined responses like successful payment processing or a failed transaction response.
Technical Application: In many unit testing frameworks, such as Mockito in Java or Moq in .NET, you set up expectations on the mocks: specifying which methods will be called, setting their return values or even verifying interaction patterns.
Stubbing
Definition: Stubbing involves replacing a component with a simplified version that returns predetermined responses to calls made during the test. It is most useful when you need to test the internal logic of a component but aren't concerned with its interactions with associated units.
Example and Usage: In an application that fetches data from a database, if you need to test a function that processes data coming from a database, you can use a stub to simulate the database responses. This stub can return fixed records whenever queried, allowing the function to be tested without actually connecting to a database.
Technical Application: Tools like Sinon in JavaScript provide straightforward stubbing capabilities where you can easily control the behavior of functions, and reset those behaviors between tests if needed.
Faking
Definition: Faking involves creating a simpler implementation of a complex interface that behaves like the original in a superficial manner but is internally much simpler. Fakes generally have a working implementation, but take shortcuts and are not suitable for production.
Example and Usage: If an application uses a complex data sorting algorithm that interacts with a large amount of data, during testing, a Fake might use a much simpler sorting mechanism that does not involve database operations.
Technical Application: Fakes can be hand-crafted as needed, or sometimes generated by broader frameworks that support testing, such as Enterprise Library in .NET.
Comparison Table
| Feature | Mocking | Stubbing | Faking |
| Purpose | Checks interactions | Isolates code for testing | Simplifies complex implementations |
| Complexity | High (behavior mimicking) | Medium (predefined replies) | Low (simplified version) |
| Control | High (expects interactions) | Low (fixed responses) | Medium (basic functions) |
| Usage | Interaction-focused testing | Component isolation testing | Practical testing on simpler scale |
When to Use What?
- Faking is useful when you need a simple way to simulate complex logic without delving into intricate details.
- Stubbing is preferred when you need to test the functionality of a component in isolation and don’t care about the interactions with external systems.
- Mocking is essential when the focus of your testing is on the behavior and interactions with external systems or components.
In conclusion, the choice between faking, mocking, and stubbing depends largely on what aspect of the software is being tested and the specific requirements of the test environment. They are invaluable tools in a developer’s testing arsenal, helping ensure that units are tested in a thorough, logical, and efficient manner.

