Skip to main content

Test Stub

Updated 3 min read

Share this page

Send the link, quote the definition with a link back, or show it as a card on your own site.

https://softwaredictionary.org/terms/test-stub

In short

A test stub is a stand-in for a real dependency that returns prepared answers during a test, so code can be tested without the real database or service.

What is a test stub?

A test stub replaces a dependency of the code under test, such as an API client, a database query or the system clock, with a simple object that returns canned answers: values written into the test in advance. When the code asks the stub for an exchange rate, it gets 0.9; when it asks for the date, it gets January 1. The test then checks what the code did with those answers.

Stubs let a test control the indirect inputs of the code, meaning the data it receives from the objects it calls rather than through its own arguments. That makes it easy to create situations that are hard to trigger for real: a payment gateway that declines a card, an API that times out, a search that finds nothing. A stub is like a stand-in reading fixed lines from a script at a rehearsal, so the lead actor can practice the scene; nobody grades the stand-in.

The term comes from Gerard Meszaros's 2007 book xUnit Test Patterns, which names five kinds of test double: dummy, stub, spy, mock and fake. You can write a stub by hand as a small object, or create one with a library: Mockito's when(...).thenReturn(...), Jest's mockReturnValue, Sinon's sinon.stub() and Python's Mock(return_value=...) all create stubs, even though these tools often call everything a mock.

Stubs and mocks are the pair most often confused. A stub only supplies answers, and the test asserts on the result or the state of the code under test; a mock also carries expectations about how it is called, and the test fails if, say, sendEmail wasn't called exactly once. In Martin Fowler's terms, stubs support state verification and mocks support behavior verification. Prefer stubs when only the outcome matters, because tests that check every call tend to break whenever the implementation changes.

Key takeaways

  • A test stub replaces a real dependency and returns canned answers.
  • It controls the indirect inputs of the code under test, including hard-to-trigger errors.
  • A stub never fails a test by itself; the test asserts on the result.
  • A mock also verifies how it was called; a stub doesn't.
  • Dummies, stubs, spies, mocks and fakes are all test doubles.

Example

A hand-written stub for an exchange rate service (Jest)javascript
// The code under test asks a rates service for the current exchange rate
function toEuros(amountUsd, ratesService) {
  return amountUsd * ratesService.getRate("USD", "EUR");
}

// The stub: no network, no logic, just a canned answer
const ratesStub = { getRate: () => 0.9 };

test("converts dollars to euros", () => {
  expect(toEuros(100, ratesStub)).toBe(90); // check the result, not the calls
});

// A mock would also check that getRate was called with ("USD", "EUR").

Readers ask

What is the difference between a stub and a mock?

A stub returns prepared answers so the code under test can run, and the test then checks the result. A mock also records its calls and checks them against expectations, so the test can fail because the code called it the wrong way.

What is the difference between a stub and a fake?

A stub returns fixed answers and has no real logic. A fake is a working but simplified implementation, such as an in-memory database that really stores and finds records, and suits tests that need realistic behavior across many calls.

When should I use a stub?

When the code under test needs data from a slow, unreliable or costly dependency, or when you need a specific answer such as an error or an empty list. If the outcome that matters is a call to another system, such as sending an email, a mock or a spy fits better.

See also

Sources

Spotted a mistake or something missing on this page?Suggest an edit

More

Settings