Se moquant d'un Django Queryset afin de tester une fonction qui prend un queryset
J'ai une fonction d'utilité dans mon projet Django, il faut un queryset, obtient quelques données et renvoie un résultat. Je voudrais écrire quelques tests pour cette fonction. Est de toute façon il 'maquette' un QuerySet? J'aimerais créer un objet qui ne touche pas à la base de données, et je peux lui fournir une liste de valeurs à utiliser (c'est à dire des faux lignes) et puis il va agir comme un queryset, et permettra à quelqu'un de faire le champ des recherches sur elle/filtre/obtenir/etc tous.
N'a rien de ce genre existent déjà?
Vous devez vous connecter pour publier un commentaire.
Pas que je sache, mais pourquoi ne pas utiliser un réel queryset? Le framework de test est tous mis en place pour vous permettre de créer des données de l'échantillon à l'intérieur de votre test, et la base de données est créée pour chaque test, donc il ne semble pas être une raison de ne pas utiliser la chose réelle.
Bien sûr, vous pouvez simuler une QuerySet, vous pouvez vous moquer de quelque chose.
Vous pouvez créer un objet vous-même, et de lui donner une interface dont vous avez besoin, et de l'avoir de retour de toutes les données que vous le souhaitez. Au cœur, en se moquant n'est rien de plus que de fournir une "double" qui agit assez comme la vraie chose pour vos tests objectifs.
Le low-tech façon de commencer est de définir un objet:
alors créer l'un de ces, et le remettre à votre test. Le test échouera probablement sur un
AttributeError
. Qui vous dira ce que vous devez mettre en œuvre sur votreMockQuerySet
. Répétez jusqu'à ce que votre objet est assez riche pour vos tests.Je vais avoir le même problème, et il ressemble à la personne agréable a écrit une bibliothèque pour se moquant de QuerySets, il est appelé maquette de django et le code spécifique que vous aurez besoin est ici https://github.com/dcramer/mock-django/blob/master/mock_django/query.py je pense que vous pouvez ensuite simplement patch vous les modèles les objets de la fonction de retour de l'un de ces QuerySetMock les objets que vous avez mis en place pour revenir à quelque chose d'attendu!
Vide Queryset, j'irais tout simplement pour l'utilisation de
none
comme keithhackbarth a déjà déclaré.Cependant, pour se moquer d'un Queryset qui renvoie une liste de valeurs, je préfère utiliser un Maquette avec un
spec
du Modèle du manager. À titre d'exemple (Python 2.7 style - J'ai utilisé l'externe se Moquer de la bibliothèque), voici un test simple où le Queryset est filtré, puis comptés:Cependant, pour répondre à la question, au lieu de mettre un
return_value
pourcount
, ce qui pourrait facilement être ajusté à unlist
des instances de modèle retourné à partir deall
.Noter que le chaînage est gérée par le réglage de la
filter
pour retourner la moqué de queryset:Cela devrait être appliquée pour tout queryset les méthodes utilisées dans la fonction en cours de test, par exemple
exclude
, etc.Pour cela, j'utilise De Django reinhardt .aucune fonction() .
Par exemple:
C'est la méthode utilisée fréquemment dans Django interne de cas de test. Sur la base des commentaires dans le code
.none
! Merci c'est super utile.Avez-vous regardé dans FactoryBoy? https://factoryboy.readthedocs.io/en/latest/orms.html
C'est une des luminaires outil de remplacement avec l'appui de l'orm de django - usines essentiellement générer orm comme des objets (soit dans la mémoire ou dans une base de données de test).
Voici un excellent article pour commencer: https://www.caktusgroup.com/blog/2013/07/17/factory-boy-alternative-django-testing-fixtures/
Essayer le
django_mock_queries
de la bibliothèque qui vous permet de se moquer de la base de données d'accéder et d'utiliser certaines de Django requête ensemble des fonctionnalités comme le filtrage.Divulgation complète: je contribué à certaines fonctionnalités du projet.
Vous pouvez se moquer comme ceci:
Un premier conseil serait de diviser la fonction en deux parties, une qui crée le queryset
et celui qui manipule la sortie de il. De cette façon, test de la deuxième partie est simple.
Pour le problème de base de données, j'ai étudié le cas de django utilise sqlite en mémoire et j'ai trouvé que
récente version de django utilise sqlite -base de données en mémoire, à partir de Le django unittest page:
Se moquant de l'objet QuerySet ne fera pas de vous exercer sa pleine logique.