Skip to content

Instantly share code, notes, and snippets.

@TomFaulkner
Created January 7, 2023 00:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TomFaulkner/5d5b6ab98e32c08b1a9831d3c95dd77e to your computer and use it in GitHub Desktop.
Save TomFaulkner/5d5b6ab98e32c08b1a9831d3c95dd77e to your computer and use it in GitHub Desktop.
Monkeypatch Python functools.partials

Monkeypatching Python Partials

Python functools.partial instances bind the function before monkeypatch can get at the function. This makes patching them out difficult and tedious.

This fixture finds all partials in a module and replaces them with MagicMocks then yields the MagicMock to assert against.

This might be useful if the partials were calls to an API or service where we just want to make sure a call was made.

In my actual case these were calls to publish to various AWS SNS topics. The partials populate the topic ARN from an imported environment variable. I felt it sufficient to test that one of the calls was used rather than patch each one individually.

I think the code should run, but I've only actually run the fixture, the rest is just an example I wrote in gist to explain it.

from functools import partial
import boto3
def _publish(msg: str, topic: str) -> None:
boto3.client('sns').publish(TopicArn=topic, Message=msg)
new_order = partial(_publish, topic='new order arn')
new_customer = partial(_publish, topic='new customer arn')
def function_under_test():
return new_customer('John Doe')
from functools import partial
from unittest.mock import MagicMock
import pytest
import subject
@pytest.fixture
def partials_mock(monkeypatch)
mm = MagicMock()
for attr in dir(sns):
if isinstance(getattr(sns, attr), partial):
monkeypatch.setattr(f'subject.{attr}', mm)
yield mm
def test_function_under_test_calls_a_partial(partials_mock):
subject.function_under_test()
partials_mock.assert_called_once_with('John Doe')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment