Lingua-e
← Comparisons

stub vs mock vs fake vs spy

Stub: returns preset values, no verification. Mock: verifies that specific calls happened. Fake: a real working lightweight implementation. Spy: wraps the real thing and records calls without replacing it.

stub

Returns hardcoded or predefined values. It replaces a real dependency so the test can run, but it does not record or verify anything about how it was called.

"const stub = { getUser: () => ({ id: 1, name: 'Test' }) };"

mock

A test double that also verifies behavior. After the test runs you assert that specific calls were made with specific arguments. It fails the test if your code did not interact with it as expected.

"expect(mockEmailService.send).toHaveBeenCalledWith('welcome', user.email);"

fake

A working lightweight implementation of a real dependency. An in-memory database is a classic fake. It behaves correctly but is simpler and faster than the real thing.

"class FakeUserRepository implements UserRepository { private users = new Map(); ... }"

spy

Wraps the real implementation instead of replacing it. The real code still runs, but the spy records all calls so you can inspect them afterward.

"const spy = jest.spyOn(emailService, 'send'); // real method still runs"

Interview tip

Most developers use "mock" to mean any test double. That's fine in conversation. But if an interviewer specifically asks the difference, the key distinction is: stubs provide data, mocks verify behavior.

Other comparisons

Was this page helpful?

Ready to practice your English at work?

Lingua-e has interactive exercises built around real developer conversations: standups, code reviews, retrospectives, and more. Practice until it comes naturally.

Try Lingua-e for free