In our Django project, we have a receiver function for post_save signals sent by the User model:
@receiver(post_save, sender=User)
def update_intercom_attributes(sender, instance, **kwargs):
# if the user is not yet in the app, do not attempt to setup/update their Intercom profile.
if instance.using_app:
intercom.update_intercom_attributes(instance)
This receiver calls an external API, and we'd like to disable it when generating test fixtures with factory_boy. As far as I can tell from https://factoryboy.readthedocs.io/en/latest/orms.html#disabling-signals, however, all one can do is mute all post_save signals, not a specific receiver.
At the moment, the way we are going about this is by defining an IntercomMixin which every test case inherits from (in the first position in the inheritance chain):
from unittest.mock import patch
class IntercomMixin:
@classmethod
def setUpClass(cls):
cls.patcher = patch('lucy_web.lib.intercom.update_intercom_attributes')
cls.intercomMock = cls.patcher.start()
super().setUpClass()
@classmethod
def tearDownClass(cls):
super().tearDownClass()
cls.patcher.stop()
However, it is cumbersome and repetitive to add this mixin to every test case, and ideally, we'd like to build this patching functionality into the test factories themselves.
Is there any way to do this in Factory Boy? (I had a look at the source code (https://github.com/FactoryBoy/factory_boy/blob/2d735767b7f3e1f9adfc3f14c28eeef7acbf6e5a/factory/django.py#L256) and it seems like the __enter__ method is setting signal.receivers = []; perhaps this could be modified so that it accepts a receiver function and pops it out of the the signal.receivers list)?