Test Doubles: Replacing real objects for testing
Tags: testing, tdd, refactoring
Published: 2021-08-18 17:24:30

## 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.**

<img src="https://miro.medium.com/max/1290/1*Yzzk9bNkuXumtXPNVoDorQ.png"></img>

<em> Removed from Unit Testing Principles, Practices, and Patterns (Vladimir Khorikov).</em>

## 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] (https://martinfowler.com/articles/mocksArentStubs.html)
[Unit Testing Principles, Practices, and Patterns](https://www.amazon.com.br/Unit-Testing-Principles-Practices-Patterns/dp/1617296279)