Mocking in Go: Swap Real Code for Test Doubles
Mocking in Go uses interfaces to swap slow dependencies like time.Sleep with fast fakes in tests, keeping your test suite quick. Use it for network calls or database access. The footgun is testing implementation details instead of observable behavior.
Why it exists
Tests must be fast to provide a quick feedback loop. When a function depends on something slow, like a network call or a timed pause, the tests for that function become slow. This harms developer productivity by making the test-edit-run cycle painful. Mocking was invented to isolate code from slow dependencies, allowing tests to run in milliseconds.
The mental model
Instead of your function depending on a concrete, slow implementation (like the global time.Sleep function), it depends on an interface you define. In your application's main entrypoint, you provide the real implementation that actually pauses. In your tests, you provide a "mock" or "fake" implementation that satisfies the same interface but runs instantly.
How it works
The process is dependency injection. First, identify the slow dependency, like time.Sleep. Second, define an interface that describes the necessary behavior, for example, a Sleeper interface with a Sleep() method. Third, refactor your function to accept this interface as an argument. Fourth, create a real struct that implements this interface by calling the actual time.Sleep. Finally, for your tests, create a mock struct that also implements the interface but does nothing or simply records that it was called. This lets your test run without any actual delay.
When to use it
Use mocking when testing functions that interact with external systems or dependencies that are slow, non-deterministic, or have side effects. This includes network services, database connections, filesystem operations, and system clocks or timers. The goal is to isolate your function from these external factors to test its logic in a fast and predictable way.
When not to use it
Avoid mocking dependencies that are already fast, deterministic, and have no side effects, such as pure utility functions. Overusing mocks for simple, internal logic can make tests more complex and brittle than the code they are testing, and they can obscure the actual behavior being tested.
One canonical example
A Countdown function prints 3, 2, 1, Go!, with a one-second pause between each print. The time.Sleep call makes testing slow. To fix this, you define a Sleeper interface with a Sleep() method. The Countdown function is changed to accept a Sleeper. In main, you pass a real sleeper that calls time.Sleep. In the test, you pass a MockSleeper whose Sleep() method is empty or just increments a counter. This allows the test to verify the countdown logic and output instantly without waiting.
Interview question
What is the main reason for employing mocking in Go unit tests?
- a.To reduce the overall number of test cases required for comprehensive coverage.
- b.To verify the exact sequence of internal method calls within a function.
- c.To ensure that all external API calls are made correctly.
- d.To isolate the code under test from slow or unpredictable dependencies.Correct
Why? this is the answer
The card emphasizes that mocking's primary purpose is to make tests fast by isolating the code under test from slow, non-deterministic, or side-effect-prone dependencies. While mocking can aid in verifying correctness, its core benefit is enabling quick and predictable test execution. Testing internal call sequences is explicitly warned against as a 'footgun'.
Just read this? Test yourself on what you have been reading.
Read the original → quii.gitbook.io
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on go — each one lists the topics its interview covers.
See open roles