variable template tag examples bootstrap django django-testing django-signals

template - ¿Quieres deshabilitar las señales en las pruebas de Django?



django{% block %} (4)

Encontré esta pregunta cuando buscaba deshabilitar una señal para un conjunto de casos de prueba y la respuesta de Germano me llevó a la solución, pero toma el enfoque opuesto, así que pensé en agregarla.

En tu clase de prueba:

class MyTest(TestCase): def setUp(self): # do some setup signal.disconnect(listener, sender=FooModel)

En lugar de agregar el código de decisión al agregar la señal, en su lugar, la deshabilité en el punto de la prueba, lo que me parece una solución más agradable (ya que las pruebas deben escribirse alrededor del código en lugar del código alrededor de las pruebas). ¡Ojalá sea útil para alguien en el mismo barco!

Edición: desde que escribí esto, me han presentado otra forma de deshabilitar las señales para las pruebas. Esto requiere el paquete factory_boy (v2.4.0 +) que es muy útil para simplificar las pruebas en Django. Estás realmente arruinado por la elección:

import factory from django.db.models import signals class MyTest(TestCase): @factory.django.mute_signals(signals.pre_save, signals.post_save) def test_something(self):

Advertencia gracias a las mejoras: silencia las señales dentro de la fábrica y cuando se crea un objeto, pero no más dentro de la prueba cuando se quiere hacer explícita la señal guardar (): la señal no se silenciará allí. Si este es un problema, entonces usar la simple desconexión en setUp es probablemente el camino a seguir.

Así que tengo varias señales y controladores que se envían a través de aplicaciones. Sin embargo, cuando realizo pruebas / entro en ''modo de prueba'', quiero que estos controladores estén deshabilitados.

¿Existe una forma específica de Django para desactivar las señales / manejadores cuando se está en modo de prueba? ¿Puedo pensar en una forma muy simple (de incluir a los manejadores dentro de una cláusula if TESTING) pero me preguntaba si había una mejor manera integrada en Django? ...


Este es un ejemplo completo con importaciones sobre cómo deshabilitar una señal específica en una prueba, si no desea utilizar FactoryBoy.

from django.db.models import signals from myapp.models import MyModel class MyTest(TestCase): def test_no_signal(self): signals.post_save.disconnect(sender=MyModel, dispatch_uid="my_id") ... after this point, the signal is disabled ...

Esto debería coincidir con su receptor, este ejemplo coincidiría con este receptor:

@receiver(post_save, sender=MyModel, dispatch_uid="my_id")

Intenté deshabilitar la señal sin especificar dispatch_uid y no funcionó.


No no hay. Aunque puedes hacer una conexión condicional fácilmente:

import sys if not ''test'' in sys.argv: signal.connect(listener, sender=FooModel)


Tuve un problema similar y no pude desconectar exitosamente mi señal usando a signals.post_save.disconnect() . Encontré this enfoque alternativo que crea un decorador para anular la configuración de SUSPEND_SIGNALS en pruebas y señales específicas. Podría ser útil para cualquiera en el mismo barco.

Primero, crea el decorador:

import functools from django.conf import settings from django.dispatch import receiver def suspendingreceiver(signal, **decorator_kwargs): def our_wrapper(func): @receiver(signal, **decorator_kwargs) @functools.wraps(func) def fake_receiver(sender, **kwargs): if settings.SUSPEND_SIGNALS: return return func(sender, **kwargs) return fake_receiver return our_wrapper

Reemplace el decorador habitual de @receiver en su señal con el nuevo:

@suspendingreceiver(post_save, sender=MyModel) def mymodel_post_save(sender, **kwargs): work()

Use override_settings() Django en su TestCase:

@override_settings(SUSPEND_SIGNALS=True) class MyTestCase(TestCase): def test_method(self): Model.objects.create() # post_save_receiver won''t execute

Gracias a Josh Smeaton, quien escribió el blog.