Quelle serait une manière élégante de tester unitaire une méthode comme celle-ci?
from feedgen.feed import FeedGenerator
def generate_feed(file_list):
fg = FeedGenerator()
for f in file_list:
fe = fg.add_entry()
fg.rss_str(pretty=True)
fg.rss_file('podcast.xml')
De toute évidence, la méthode ne renvoie aucune valeur, mais écrit un fichier xml à la place. Existe-t-il une manière élégante de tester cela? Ou devrais-je envisager de refactoriser ma méthode pour la rendre plus conviviale pour les tests unitaires et m'affirmer contre quelque chose?
3 Réponses :
Vous pouvez tester pour voir si le fichier est réellement créé, dans le bon chemin, et le supprimer après cela (car ce n'est qu'un test) si cela vous concerne. Vous pouvez même lire le fichier pour voir s'il est correctement configuré.
Vous pouvez également demander à cette fonction de renvoyer True de False en cas de succès ou d'échec lors de l'écriture du fichier, et de les tester (par exemple, si vous savez cas qui DEVRAIENT échouer).
Un autre test utile serait de simplement vérifier que la méthode ne génère pas d'erreur dans diverses conditions.
La manière standard de faire cela serait d'utiliser patch et mock pour se moquer de la classe FeedGenerator .
Si vous passez le FeedGenerator en tant qu'argument, vous n'avez pas besoin de patch:
file_list = [File("foo"), File("bar")] # or whatever?
fg = MagicMock(spec=FeedGenerator)
generate_feed(file_list, fg)
assert fg.add_entry.call_count == len(file_list)
# etc
Maintenant, votre test peut faire:
def generate_feed(file_list: List[File], fg: FeedGenerator) -> None:
# do stuff to fg based on file_list
rss_file peut prendre un nom de fichier ou un objet de type fichier comme argument. Réécrivez generate_feed pour accepter un argument qui est passé à rss_file.
f = io.StringIO() generate_feed(file_list, f)
En production, vous pouvez écrire
generate_feed(file_list)
ou simplement
with open("podcast.xml", "w") as f:
generate_feed(file_list, f)
Pour les tests, vous pouvez utiliser un objet StringIO .
def generate_feed(file_list, fobj="podcast.xml"):
fg = FeedGenetaror()
for f in file_list:
fe = fg.add_entry()
fg.rss_str(pretty=True)
fg.rss_file(fobj)
Ensuite, vous pouvez tester le contenu de f (via f.getvalue () ) comme s'il s'agissait du fichier XML que vous avez généré. p >