English for Jest Mocking
Learn the English vocabulary for Jest mocking: mock functions, spies, and module mocks, explained for discussing test isolation clearly.
“I mocked it” gets used loosely for at least three different techniques in Jest — a bare mock function, a spy on a real implementation, and a full module mock — and picking the wrong term in a code review makes it harder to tell what a test is actually isolating.
Key Vocabulary
Mock function — a function created with jest.fn() that records how it was called (arguments, call count) and returns a configurable value, standing in for a real dependency without invoking its actual behavior.
“We pass a mock function as the callback and assert it was called exactly once with the expected payload, instead of relying on the real callback’s side effects.”
Spy — a mock wrapped around an existing function (jest.spyOn) that can either preserve the original implementation or replace it, letting you observe calls to a real method without fully replacing it.
“We used a spy on the logger’s error method so we could assert it was called during the failure case, without silencing all the other real logging behavior.”
Module mock — replacing an entire imported module with a fake implementation using jest.mock(), commonly used to isolate a unit under test from a dependency like a database client or an HTTP library.
“We module-mocked the API client so the component test doesn’t make real network calls — it just returns a canned response we control.”
Mock implementation — the specific behavior configured for a mock function to execute when called, set with mockReturnValue, mockResolvedValue, or mockImplementation, determining what the test actually exercises.
“We set a mock implementation that throws on the second call, to test the retry logic without needing to actually trigger two real failures.”
Test double — the general term for any stand-in object used in place of a real dependency during a test, encompassing mocks, spies, stubs, and fakes as specific varieties. “Mocks, spies, and fakes are all types of test doubles — the term you use should match which one you’re actually reaching for.”
Common Phrases
- “Is this a mock function, or a spy on the real implementation?”
- “Are we module-mocking the whole dependency, or just stubbing one method?”
- “What’s the mock implementation returning for this test case?”
- “Is this test double actually necessary here, or could we use the real dependency safely?”
- “Did we reset the mock between tests, or is state leaking across them?”
Example Sentences
Explaining a test isolation choice in review: “We’re module-mocking the payment client entirely, since we don’t want any test hitting a real payment API — the mock implementation just returns a successful charge response by default, and individual tests override it for the failure cases.”
Debugging flaky test failures:
“The mock function wasn’t being reset between tests, so call counts from the previous test were leaking into the next one’s assertions — adding mockClear() in beforeEach fixed it.”
Reviewing an over-mocked test: “This test mocks so much of the module that it’s barely testing our actual logic anymore — could we use a spy instead, so the real implementation still runs and we just observe the call?”
Professional Tips
- Use mock function specifically for a bare
jest.fn()and spy forjest.spyOn()— the distinction matters because a spy can preserve real behavior while a plain mock never does. - Say module mock when the entire dependency is replaced, not just “we mocked it” — reviewers need to know the scope of what’s faked to judge whether the test is meaningful.
- Describe the mock implementation explicitly when a test’s behavior depends on it — “the mock returns X” is more useful in a PR description than just “we mocked the dependency.”
- Reach for test double as the general term when the specific technique doesn’t matter to the point being made, but default to the precise term (mock, spy, stub, fake) whenever it does.
Practice Exercise
- Write a sentence distinguishing a mock function from a spy.
- Explain what a module mock replaces and why you’d use one.
- Describe why resetting mocks between tests matters.
In Practice: Navigating Feedback and Collaboration
The core of effective communication in a professional development environment isn’t just about knowing what to test; it’s about articulating why you’re testing it that way. When using Jest with mocking, particularly when providing feedback on pull requests or participating in code reviews, your phrasing significantly impacts how your suggestions are received and implemented. Many non-native English speakers find the nuances of technical vocabulary challenging – specifically, conveying the precise intent behind a mock function versus a spy, or understanding why module mocks might be necessary. It’s easy to fall into overly prescriptive language, which can feel like an attack on someone’s code rather than a constructive contribution.
A common scenario arises during a code review of a feature implementing user authentication. A developer has written a test that uses jest.spyOn() on the AuthService object, intending to verify that its login method is called with specific parameters. However, another reviewer might respond with: “This spy isn’t sufficient. We need a module mock here. The AuthService depends on several internal services – database connections, token generation logic – and this test is only isolating the login call itself. A module mock would allow us to fully control all dependencies, ensuring we’re testing the entire authentication flow, not just the surface-level interaction.” The difference lies in the reasoning behind the recommendation. The first reviewer focused on a specific observable behavior (the spy), while the second highlighted the broader architectural context and the need for comprehensive isolation. Using phrases like “ensure complete isolation” or “verify all dependencies” communicates a deeper understanding of testing principles beyond simply pointing out an incomplete mock. Furthermore, framing it as a way to improve test coverage is often more palatable than stating that the initial approach was “wrong.”
Another situation involves a Slack message discussing a failing test. A junior developer might type: “The getData function isn’t mocked correctly.” This could lead to frustration and a defensive reaction. A better phrasing would be, “I’m seeing intermittent failures with getData. To help us pinpoint the root cause, could we explore using a module mock for the DataService? That way, we can systematically control its return values during the test and rule out any potential issues related to external data sources.” Notice how this approach focuses on problem-solving (“pinpoint the root cause”) and offers a concrete solution – a module mock – rather than simply criticizing the current state.
Finally, when writing PR descriptions for tests that utilize mocks, be clear about what you’re mocking and why. Don’t just say “Mocked dependencies.” Instead, describe the specific aspects of the dependency being controlled: “Module mock created for DatabaseConnection to simulate different connection states and ensure robust error handling during data retrieval.”
# Example using Jest to create a module mock for the DatabaseConnection class.
// Assuming you have a DatabaseConnection class defined elsewhere...
const { DatabaseConnection } = require('./database_connection'); // Replace with your actual path
jest.mock('./database_connection', () => ({
getConnection: jest.fn(() => ({
query: jest.fn((sql, params) => Promise.resolve({ rows: [{id: 1}] })), // Mock query function
close: jest.fn()
}))
}));
This example demonstrates a practical application of module mocks – controlling the behavior of the DatabaseConnection object to simulate different scenarios during testing. The key takeaway is that precision and context are paramount when discussing Jest mocking with colleagues, especially those whose first language isn’t English.