How do I mock a django signal handler?
Possibly a better idea is to mock out the functionality inside the signal handler rather than the handler itself. Using the OP's code:
@receiver(post_save, sender=User, dispatch_uid='myfile.signal_handler_post_save_user')def signal_handler_post_save_user(sender, *args, **kwargs): do_stuff() # <-- mock thisdef do_stuff(): ... do stuff in here
Then mock do_stuff
:
with mock.patch('myapp.myfile.do_stuff') as mocked_handler: self.assert_equal(mocked_handler.call_count, 1)
So, I ended up with a kind-of solution: mocking a signal handler simply means to connect the mock itself to the signal, so this exactly is what I did:
def test_cache(): with mock.patch('myapp.myfile.signal_handler_post_save_user', autospec=True) as mocked_handler: post_save.connect(mocked_handler, sender=User, dispatch_uid='test_cache_mocked_handler') # do stuff that will call the post_save of User self.assertEquals(mocked_handler.call_count, 1) # standard django # self.assert_equal(mocked_handler.call_count, 1) # when using django-nose
Notice that autospec=True
in mock.patch
is required in order to make post_save.connect
to correctly work on a MagicMock
, otherwise django will raise some exceptions and the connection will fail.
take a look at mock_django . It has support for signals
https://github.com/dcramer/mock-django/blob/master/tests/mock_django/signals/tests.py