From Mock to Clear Precise Communication
I know, everything is called a “mock” these days. You write tests with a mocking framework, it creates stand-in objects to replace dependencies. And they are all called mocks.
But a mock is only one type of test double.
In reality, we have Dummies, Stubs,
Spies, Mocks, and Fakes. Using
“mock” for all of them hides the purpose of the specific test
double.
Suppose we’re testing whether a method throws an ArgumentException. The class under test requires a data repository to be injected, but the exception should be thrown before the repository is ever used. In this case, the repository is irrelevant to our test.
Instead of
// Arrange
var mock = CreateMock<IRepository>();
InsertOrderHandler handler = new(mock)we can make our intent clearer by using a dummy:
// Arrange
var dummy = CreateMock<IRepository>();
InsertOrderHandler handler = new(dummy)Note: I’m using
CreateMock<IRepository>()here as an example for whatever framework is being used.
Now consider a scenario where the repository does matter. Our test needs it to return specific data in order to pass.
// Arrange
var mock = CreateMock<IRepository>();
GetOrderHandler handler = new(mock)We can clearly communicate that the repository is needed for the test to pass.
// Arrange
var stub = CreateMock<IRepository>();
GetOrderHandler handler = new(stub)Or consider a scenario where we need to verify that the correct data is written to the database.
// Arrange
var spy = CreateMock<IRepository>();
InsertOrderHandler handler = new(spy)
Order order = CreateValidOrder();
// Act
handler.Handle(validOrder);
// Assert
Assert.Equal(123, spy.InsertedOrders[0].CustomerId)Finally, a mock is like a spy with built‑in expectations: it verifies that certain calls happened exactly as specified. This verification happens in the Assert phase.
// Assert
mock.Verify(r => r.Insert(validOrder));The verification here is performed by the mocking framework, not by explicit assertions in the test. It hides the validation logic from the reader, they must understand the mock’s setup and Verify call to know what is actually being tested.
Being precise about test double terminology improves clarity, communicates intent, and shows you understand your craft.