What it is?
Test Doubles are objects that mimic real objects. This give us the possibility to simulate an external dependency to the SUT (System under Test) or any other real element under test. This approach is widely used in unit tests, focused in ensure the unit's assertiveness, ignoring anything outside this scope.
"Test Double is a generic term for any case where you replace a production object for testing purposes." ~Martin Flower.
Gerard Meszaros (creator of Test Doubles) divides this into five categories: Mocks, Stubs, Fakes, Spies e Dummies.
- Dummy: is an object passed around but never actually used. Used to fill parameter lists.
- Fake: is an object that have working implementations, but are not suitable for production.
- Spies: are stubs that record some information based on how they were called. One example of this might be an email service that records how many messages it was sent.
- Mocks: predefined implementations with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.
- Stubs: provide canned answers to calls made during the test, not responding at all to anything outside what's programmed in for the test.
Furthermore, these five categories can be reduced into just two groups: Mocks and Stubs.
Removed from Unit Testing Principles, Practices, and Patterns (Vladimir Khorikov).
Mocks and Stubs
Mocks
Mocks are generally used to simulate outbound interactions. They are used to control and inspect fake calls to a dependency. We can simulate and test if one or more methods were called/not called, the order in which these methods were called, whether those methods were called with the right arguments, and how many times they were called.
Usage
✅ You can use Mocks to:
- Test if external dependency methods were called as expected.
- Test how many times an external dependency method were called.
- Test if an external dependency method was called with the correct arguments.
🚫 Do not use Mocks to:
- To test function return values.
- To test function behaviors.
Stubs
Stubs are generally used to simulate inbound interactions. Different from Mock, stubs are defined objects, ready to be used. They don't know how to answer how many times an external dependency method was called/not called and which parameters were used, they just return an object already defined. In other words, a stub is the final return of a method.
Usage
✅ You can use Stubs to:
- Test the SUT behaviors when receiving different returns from an external dependency.
🚫 Do not use Stubs to:
- Test if external dependency methods were called.
- Test external dependency methods behaviors.
What about Fakes, Spies and Dummies?
They are complementary to the groups cited, helping the proper creation of Mocks and Stubs.
Fakes
Fakes (also known as Fakers) are real implementations of an external dependency, but are not suitable to production. They are generally used when we need a real functionality (or as close as possible to a real one). The most common example is to use an in-memory database to persist data. Fakers are useful in functional testing or integration testing, but are not recommended for unit testing where we can supply our needs with stubs.
Spies
Spies are objects that record their interactions to other objects (can be compared to a combination of Mock and Stub). They can be used to test both inbound and outbound interactions.
Dummies
Dummies are the simplest piece of an test, used to fill a method signature. Their only purpose is to fill a necessary space, having no effect in the test.
References
Mocks aren't Stubs
Unit Testing Principles, Practices, and Patterns
Top comments (0)