Start naming your test doubles correctly
Tags: testing, tdd, communication, mocking
Published: 2020-07-30 10:07:02

---
title: Start naming your test doubles correctly
published: true
description: A lot of developers are very vague when they name their test doubles which makes tests needlessly more difficult to understand. This posts hopes to address that issue and help you improve the readability of your tests
tags: testing, tdd, communication, mocking
canonical_url: https://quii.dev/Start_naming_your_test_doubles_correctly
---

A lot of developers are very vague when they name their test doubles which makes tests needlessly more difficult to understand. 

In conversation there’s also often ambiguities which cause problems

I overheard on a podcast

> Have you ever used a mock where you make assertions on the call?

This post will hopefully illuminate why that sentence is a bit silly!

By making a little more effort to be precise with your naming, you can communicate the intent of your tests and the design of your system more effectively

## Quick primer on dependencies

To separate concerns, we often make objects that will “depend” on other objects. 

We “inject” or “pass in” these dependencies when we construct them, so they can do a job. 

This is called *Dependency Injection*.

### Example

A `ShoppingCart` sends an email when its `sendOrder` method is called

We don’t want `ShoppingCart` to have to know _how_ to send emails as well as everything else so we give it an `Emailer` when we create it.

`new ShoppingCart(new MailgunEmailer())`

It can then use the emailer without having to know _how_ emails are sent, and you have your separation of concerns.

```
sendOrder() {
    // interesting domain logic
    this.emailer.send(confirmation)
}
```

This approach has implications for our tests. 

### With tests, we prefer not to use real objects for dependencies because we want to be able to control them, so we use something different

- It would not be desirable to send a real email every time a test is run.
- We sometimes depend on things that are slow, but we like our tests to be fast because feedback loops are extremely important 
- It would be hard for us to exercise failure scenarios using real dependencies. How do you get a 3rd party email service to deliberately fail?

## Use “Test Doubles”

_Not_ specifically mocks

A test double is what you inject into an "object under test" (OUT) to control a dependency. 

Like a stunt double!

### Using the precise words for test doubles helps reveal intent and documents your design more effectively

It’s not about being big and clever, it helps you communicate unambiguously. Software development is a team-sport so clear communication will help your team work better.

## The different kinds of test doubles

## Dummies

Sometimes you have arguments to functions that you don’t care about. Dummies are the arguments you pass in.

`const dummyLogger = jest.fn()`

## Stubs

Some objects will *query* dependencies for data.

*Stub* the dependency

`const stubUserService = jest.fn(() => 'Miss Jones')`

## Spies

Sometimes you want to call a method (or more abstractly _send a command_) to a dependency. 

It can be hard to tell in a test this happened from the outside as it’s an internal detail.

If you want to verify these commands, use a *spy*.

```
const spyEmailSender = jest.fn()
// do some stuff
expect(spyEmailSender.mock.calls.length).toBe(1)
```

## Fakes

Usually a “real” implementation but constrained.

Like an in-memory database.

Not as popular anymore due to things like Docker which let you spin up local versions of databases without the risk of there being differences between a fake and a real implementation.

## Mocks

Mocks are a _kind_ of test double!

Mocks are precise and encapsulate the detail of your interactions more explicitly.

You describe upfront what calls you expect on your test double
- Order
- Arguments
- Specific return values

If the object under test doesn’t call things as expected the mock will error.

So returning to 

> Have you ever used a mock where you make assertions on the call?

What is being described is just _a mock_. If you're not worried about the calls, you're talking about a _stub_.

## Why “mocking too much is bad”

The risk is your tests become needlessly precise and coupled to implementation detail.

This is also true of spies as they have a similar nature.

If you're overly specific with your mocks, when you want to refactor things you may find tests failing for annoying reasons that have nothing to do with _behaviour_.

## Why “having too many test doubles is bad”

Listen to your tests if they cause you pain

If you have many test doubles in a test **that means your OUT has many dependencies**.

Does that sound right to you? It shouldn’t and it means you probably need to take a look at your design. 

## An anecdote

Yesterday I reviewed a test which had a double named

`getterFn`

I had to spend some time reading the test to understand what was going on, it turns out it should've been called:

`spyCSVFetcher`

Once this was ascertained it turned out the writer had actually neglected to spy on the number of calls, which was actually a core part of what was supposed to be tested.

If the double had been named correctly in the first place (which is very little effort) I would know to look for assertions on the way it was called to help me understand what the intent of the code is. Instead, it took some investigation.

## Summary

Consistently using the recognised names for test doubles will help you be precise when communicating with other developers. It's a low-effort way to improve the way you work.

For instance if you name something a `dummy` rather than a `mock` the readers of your tests can forget about that particular test double and focus on the important collaborators. 

Tests should act as documentation so describing your test doubles clearly will help reveal the design of the test for maintainers.

## Quiz

- What does a test with lots of doubles tell you?
- How do you improve the design of a test with many test doubles?
- Name all the kinds of test doubles
- How is a mock different from a spy?

## Further reading

- [Martin Fowler's post "Mocks aren't stubs"](https://martinfowler.com/articles/mocksArentStubs.html) goes into this topic in great detail.
- [Learn Go with tests: Dependency Injection](https://quii.gitbook.io/learn-go-with-tests/go-fundamentals/dependency-injection)