J'ai une application Django appelée "Publisher", elle se connecte à divers signaux dans mon projet Django, et lorsqu'il leur reçoit, il envoie un message à une file de la RabbitMQ. Ce que je veux faire, c'est être capable de tester que mon code de configuration se connecte aux signaux corrects.
Ma structure d'application ressemble à: p> mon __init__.py ressemble à: p> et mes signaux.pycycxxx a pensé à corriger la fonction du récepteur et à vérifier que la simulation a été appelée lorsque j'ai envoyé le signal: p> tests.py: p> Cependant, car le module de signaux est importé et donc les connexions de signaux sont fabriqués avant que les tests soient exécutés, cette approche ne fonctionne pas car les connexions sont faites avant que la fonction soit corrigée ...... p> Quelqu'un peut-il suggérer une stratégie alternative? P> p>
4 Réponses :
J'ai couru dans le même problème moqueur que vous décrivez. Ma solution consiste à atteindre le registre des signaux de Django et à affirmer que ma fonction a été enregistrée auprès du signal correct.
Voici mon test: p> Un peu d'explication sur cette compréhension de cette liste : P> "Pre_Delete" est l'instance de django.dispatch.dispatcher.signal que je me suis soucié dans ce cas. Vous utiliseriez votre propre "my_interresting_signal" dans votre exemple. Les signaux ont une propriété interne appelée "Récepteurs", c'est une liste de deux tuples, où le deuxième élément est une faiblesse sur la fonction que vous vous enregistrez (donc r [1]). Appeler un affaife retourne le référent. P> Je devais jouer avec des faiblesses pour comprendre cela beaucoup: p> espère que cela aide cela aide. P> p>
Je ne pense pas que cela soit tout à fait raison. Si bar_func est dans modèles.py code> alors, oui, qui sera automatiquement importé par Django et donc connecté au signal. Mais si c'est dans un
signals.py code> alors ce ne sera pas nécessairement. En outre, l'acte d'importer votre réceptionnement dans le test le connectera automatiquement, de sorte que le test passera même si vous ne le connecte pas ailleurs.
@seddonyonyonyonyonyonyy Très bons points, mais techniquement, vous devez toujours utiliser un appconfig code> pour enregistrer les signaux (ou faire les importations), donc je suppose que vous pouvez supposer en toute sécurité qu'au moins cela se passe. Donc peut-être un autre test pour s'assurer que AppConfig enregistre vos récepteurs?
Pas une mauvaise idée!
Un moyen de tester si le signal est connecté le déconnecte et vérifie le résultat de cette action. Appeler Par exemple nous Voulez-vous tester que le signal modules.py p> L'appel à Il est nécessaire de connecter à nouveau le signal après le test, sinon il restera déconnecté em> p> p>
vrai code> si le signal a été déconnecté ou
false code> sinon.
post_save code> est connecté à notre
récepteur_function code>. p>
Deconnect code> doit utiliser les mêmes arguments que le
Connect code> appel (
expéditeur code>,
DisPatch_uid code>) p>
Ceci est assez difficile, car comme vous le dites, si vous vous moquez ou que vous importez quelque chose dans le fichier, vous incluez le récepteur dans, vous le connectez automatiquement. Ceci est à travers votre EM> Test Test Suite em> et pas seulement dans le fichier de test en question. Voici un extrait que vous pouvez utiliser, mais vous devez être discipliné dans la suite des commentaires concernant l'évité des importations dans le fichier de destinataires.
from django.test import TestCase class ReceiverConnectionTestCase(TestCase): """TestCase that allows asserting that a given receiver is connected to a signal. Important: this will work correctly providing you: 1. Do not import or patch anything in the module containing the receiver in any django.test.TestCase. 2. Do not import (except in the context of a method) the module containing the receiver in any test module. This is because as soon as you import/patch, the receiver will be connected by your test and will be connected for the entire test suite run. If you want to test the behaviour of the receiver, you may do this providing it is a unittest.TestCase, and there is no import from the receiver module in that test module. Usage: # myapp/receivers.py from django.dispatch import receiver from apples.signals import apple_eaten from apples.models import Apple @receiver(apple_eaten, sender=Apple) def my_receiver(sender, **kwargs): pass # tests/integration_tests.py from apples.signals import apple_eaten from apples.models import Apple class TestMyReceiverConnection(ReceiverConnectionTestCase): def test_connection(self): self.assert_receiver_is_connected( 'myapp.receivers.my_receiver', signal=apple_eaten, sender=Apple) """ def assert_receiver_is_connected(self, receiver_string, signal, sender): receivers = signal._live_receivers(sender) receiver_strings = [ "{}.{}".format(r.__module__, r.__name__) for r in receivers] if receiver_string not in receiver_strings: raise AssertionError( '{} is not connected to signal.'.format(receiver_string))
J'ai également confronté au problème de la vérification que tous les signaux requis sont connectés.
Merci pour tous vos commentaires. Comme le résultat est disponible, il est disponible SignalConnectorTestCase basé sur l'introspection (comme il a été proposé par @ Frank-t) et pour les signaux intégrés La solution de problème initial peut être effectuée comme suit: pour ses propres signaux, vous pouvez simplement appeler Vérifier code>
fonction de votre méthode de test. p> p>
Je ne sais pas si je reçois cette ligne droite mais je suive mes signaux écrivant à un journal dans la fonction de récepteur defeiver_function (* args, ** kwargs):