Accumulators Global Counter Mock in Python
Shows an accumulator-style global counter with a mock patch to control its value in tests.
Python code
32 linesimport unittest
from unittest.mock import patch
# Module-level global counter accumulator
counter = 0
def increment(by=1):
"""Increment the global counter in place (accumulator pattern)."""
global counter
counter += by
return counter
def reset():
"""Reset the counter to zero."""
global counter
counter = 0
# Example usage and test with mock
class TestCounter(unittest.TestCase):
def test_increment(self):
reset()
self.assertEqual(increment(), 1)
self.assertEqual(increment(5), 6)
def test_mock_counter(self):
reset()
with patch("__main__.counter", new=100):
self.assertEqual(increment(), 101)
self.assertEqual(counter, 0) # unchanged outside mock
if __name__ == "__main__":
unittest.main(verbosity=2)
Output
test_increment (__main__.TestCounter) ... ok
test_mock_counter (__main__.TestCounter) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
How it works
The global counter follows the accumulator pattern, updating in place with each increment call. unittest.mock.patch temporarily replaces the global variable with a controlled value, letting you test behavior under specific counter states. The with block ensures the patch is applied only inside it, leaving the real counter untouched afterward. This isolates tests from shared global state, which is crucial when multiple tests mutate the same global.
Common mistakes
- Forgetting `global counter` inside the function, causing UnboundLocalError.
- Not resetting the counter before tests, leading to order-dependent failures.
- Patching the wrong name when the function is imported from another module.
Variations
- Use a class-level accumulator with `@classmethod` instead of a global variable.
- Use `unittest.mock.patch.object` to patch a counter attribute on a class.
Real-world use cases
- Testing a Spark accumulator's value in unit tests by patching the global reference.
- Simulating a processed-record count that increments across distributed tasks for validation.
- Mocking a global error counter to verify logging behavior under injected failures.
Sponsored
More from Big data & Spark
Keep learning
Related tutorials and quizzes for this topic.