hassek

Remember

My code snippets

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 = "bububibu@gmail.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 __func__ function.

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!