{"id":1525,"library":"kgb","title":"kgb","description":"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.","status":"active","version":"7.3","language":"en","source_language":"en","source_url":"https://github.com/beanbaginc/kgb","tags":["testing","mocking","spy","unit testing","pytest","unittest"],"install":[{"cmd":"pip install kgb","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core dependency for Python >=2.7 and !=3.0-3.5, with explicit support up to 3.14.","package":"python","optional":false}],"imports":[{"note":"For unittest-based test suites, mix this into your test class.","symbol":"SpyAgency","correct":"from kgb import SpyAgency"},{"note":"Standalone assertion methods introduced in v7.0, usable without mixing SpyAgency.","symbol":"assert_spy_called_with","correct":"from kgb.asserts import assert_spy_called_with"}],"quickstart":{"code":"import unittest\nfrom kgb import SpyAgency, SpyOpReturn\n\nclass MyService:\n    def fetch_data(self, url):\n        # In a real application, this might make a network request\n        return f\"Actual data from {url}\"\n\nclass TestMyService(SpyAgency, unittest.TestCase):\n    def test_fetch_data_called_and_mocked(self):\n        service = MyService()\n        \n        # Spy on the fetch_data method and make it return a mocked value\n        self.spy_on(service.fetch_data, op=SpyOpReturn(\"Mocked Data!\"))\n        \n        # Call the method that is now spied upon\n        result = service.fetch_data(\"https://example.com/api/v1/data\")\n        \n        # Assertions using kgb's spy capabilities\n        self.assertEqual(result, \"Mocked Data!\")\n        self.assert_spy_called(service.fetch_data)\n        self.assert_spy_called_with(service.fetch_data,\n                                    \"https://example.com/api/v1/data\")\n\n# To run this example (typically done via a test runner like `python -m unittest`):\n# if __name__ == '__main__':\n#     unittest.main()","lang":"python","description":"This quickstart demonstrates how to use `kgb` within a `unittest.TestCase` to spy on a method, mock its return value, and then assert that the method was called with specific arguments. The `SpyAgency` is mixed into the test class, and `spy_on` is used to intercept calls."},"warnings":[{"fix":"Upgrade Python to 3.6+ or pin `kgb<7.0` in your dependencies. Python 3.13 and 3.14 are supported in later 7.x releases.","message":"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.","severity":"breaking","affected_versions":">=7.0"},{"fix":"Update assertion calls from `assertSpyCalledWith` to `assert_spy_called_with`, `assertHasSpy` to `assert_has_spy`, etc.","message":"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.","severity":"deprecated","affected_versions":">=7.0"},{"fix":"Directly use assertion methods on the spied function/method, e.g., `func.called_with()`. All spy interactions now behave consistently.","message":"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.","severity":"breaking","affected_versions":"<2.0 to >2.0"},{"fix":"When using `spy_on`, provide the original function's name via the `func_name` argument (e.g., `spy_agency.spy_on(BadClass.good_func, owner=BadClass, func_name='good_func')`).","message":"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.","severity":"gotcha","affected_versions":">=7.0"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}