Skip to content
Ben Christel edited this page Apr 30, 2022 · 4 revisions

A fake is a type of TestDouble that implements the same BehavioralContract as the object used in production. Because the fake behaves like the real thing, it lets us avoid the problem of Mocks that do not behave realistically and thus give false confidence that the code under test will work in production.

Example

Suppose we have an application that stores data in a key-value store. We can make our business logic code interact with the key-value store via the following interface:

interface KeyValueStore<Val: Serializable> {
  get(key: string): Val,
  set(key: string, val: Val): void,
}

In our tests for the business logic code, we can provide a simple in-memory implementation of KeyValueStore that stores data in a hashmap. In production, we might use a KeyValueStore backed by a filesystem, or Redis, or MongoDB.

We can run the same suite of ContractTests against the real and fake versions of the KeyValueStore, which provides assurance that the fake behaves like the real thing. We can thus be confident that when we wire up our business logic code to the real KeyValueStore in production, the whole application will work.

Naming

I don't really like the name "fake", because the key difference between fakes and other types of test doubles is that fakes are more "real" than the others. A "fake" implementation of an interface is, ideally, a real, working implementation that you could use in a real, working application. I might prefer to call these test doubles "toys" because they are usually small, simplified models of the real thing. However, the name "fake" is widely used, so we're probably stuck with it.

Clone this wiki locally