I was caught up into a situation where an object had a signal to create in a 3rd party API a connection every time that object was saved into our database. For automated tests this is not ideal since we are not here to test the 3rd party API (always) but our own functionality. I ran into some issues when disconnecting the signal though. Here is what I end up figuring out to fix it:
class MyObj(): @receiver(post_save, sender="MyObj") def create_obj_on_third_party_api(sender, instance, created, **kwargs): # Do your thing ---- from mock import patch from django.db.models.signals import post_save from factory import Sequence, SubFactory from factory.django import DjangoModelFactory class ObjFactory(DjangoModelFactory): class Meta: model = MyObj user = SubFactory(UserFactory) email = "email@example.com" @classmethod def _create(cls, model_class, *args, **kwargs): post_save.disconnect(model_class.create_obj_on_third_party_api.__func__, sender=model_class) with patch.object(Obj, "is_refresh_token_valid", return_value=True): obj = super(ObjFactory, cls)._create(model_class, *args, **kwargs) post_save.connect(model_class.create_obj_on_third_party_api.__func__, sender=model_class, weak=False) return obj
Django signals are handled by using the python
id function, which compares identical objects. That means it will not disconnect the signal if we pass a non identical object to which I realised the identical object was the
Also, my object checked if a refresh_token was valid before saving into DB, I ended up mocking that function to always return True.
EXTRA: If you don’t use FactoryBoy for your testing, I highly recommend it!