So I have various signals and handlers which are sent across apps. However, when I perform tests / go into 'testing mode', I want these handlers to be disabled.
Is there a Django-specific way of disabling signals/handlers when in testing mode? I can think of a very simple way (of including the handlers within an if TESTING clause) but I was wondering if there was a better way built into Django?...
Here's a full example with imports on how to disable a specific signal in a test, if you don't want to use FactoryBoy.
This should be matched against your receiver, this example would match this receiver:
I tried to disable the signal without specifying the dispatch_uid and it didn't work.
No, there is not. You can easily make a conditional connection though:
I had a similar issue and wasn't able to successfully disconnect my signal using
signals.post_save.disconnect()
. Found this alternative approach that creates a decorator to override theSUSPEND_SIGNALS
setting on specified tests and signals. Might be useful for anyone in the same boat.First, create the decorator:
Replace the usual
@receiver
decorator on your signal with the new one:Use Django's
override_settings()
on your TestCase:Thanks to Josh Smeaton, who wrote the blog.
I found this question when looking to disable a signal for a set of test cases and Germano's answer lead me to the solution but it takes the opposite approach so I thought I'd add it.
In your test class:
Instead of adding decision code to adding the signal I instead disabled it at the point of testing which feels like a nicer solution to me (as the tests should be written around the code rather than the code around the tests). Hopefully is useful to someone in the same boat!
Edit: Since writing this I've been introduced to another way of disabling signals for testing. This requires the factory_boy package (v2.4.0+) which is very useful for simplifying tests in Django. You're spoilt for choice really:
Caveat thanks to ups: it mutes signals inside factory and when an object is created, but not further inside test when you want to make explicit save() - signal will be unmuted there. If this is an issue then using the simple disconnect in setUp is probably the way to go.
If you connect receivers to signals in
AppConfig.ready
, which is recommended by documentation, see https://docs.djangoproject.com/en/2.2/topics/signals/#connecting-receiver-functions, you can create an alternativeAppConfig
for your tests with other signal receivers.