kgb
kgb is a Python library that provides utilities for creating function spies in unit tests, offering a powerful alternative to traditional mocking. It intercepts and records calls to functions, tracking arguments and return values, and can modify function behavior at the bytecode level. Unlike some mocking frameworks, kgb can spy on top-level functions in addition to class methods. It supports popular testing frameworks like unittest, pytest, nose, and nose2, and maintains an active release cadence, with recent versions adding support for the latest Python releases.
Warnings
- breaking Version 7.0 dropped official support for Python 2.6, 3.4, and 3.5. Users on these Python versions must use `kgb` versions older than 7.0.
- deprecated CamelCase assertion methods (e.g., `assertSpyCalledWith`) are deprecated in favor of snake_case equivalents (e.g., `assert_spy_called_with`) for improved readability and consistency. While the old versions still exist, new code should use snake_case.
- breaking Prior to kgb 2.0, spying on standard functions required accessing a special `.spy` attribute (e.g., `func.spy.called_with()`), which was inconsistent with methods. This `.spy` attribute has been removed.
- gotcha Spying on methods wrapped in decorators that do not preserve the original function's name can cause errors. `kgb` will attempt to detect this and warn you.
Install
-
pip install kgb
Imports
- SpyAgency
from kgb import SpyAgency
- assert_spy_called_with
from kgb.asserts import assert_spy_called_with
Quickstart
import unittest
from kgb import SpyAgency, SpyOpReturn
class MyService:
def fetch_data(self, url):
# In a real application, this might make a network request
return f"Actual data from {url}"
class TestMyService(SpyAgency, unittest.TestCase):
def test_fetch_data_called_and_mocked(self):
service = MyService()
# Spy on the fetch_data method and make it return a mocked value
self.spy_on(service.fetch_data, op=SpyOpReturn("Mocked Data!"))
# Call the method that is now spied upon
result = service.fetch_data("https://example.com/api/v1/data")
# Assertions using kgb's spy capabilities
self.assertEqual(result, "Mocked Data!")
self.assert_spy_called(service.fetch_data)
self.assert_spy_called_with(service.fetch_data,
"https://example.com/api/v1/data")
# To run this example (typically done via a test runner like `python -m unittest`):
# if __name__ == '__main__':
# unittest.main()