web-dev-qa-db-fra.com

Assert_called_with de Python, y a-t-il un caractère générique?

Supposons que j'ai une classe dans python configurée comme ceci.

from somewhere import sendmail

class MyClass:

    def __init__(self, **kargs):
        self.sendmail = kwargs.get("sendmail", sendmail)  #if we can't find it, use imported def

    def publish():

        #lots of irrelevant code
        #and then

        self.sendmail(mail_to, mail_from, subject, body, format= 'html')

Comme vous pouvez le voir, je me suis en quelque sorte donné la possibilité de paramétrer la fonction que j'utilise pour self.sendmail

Maintenant dans le fichier de test.

Class Tester():

    kwargs = {"sendmail": MagicMock(mail_from= None, mail_to= None, subject= None, body= None, format= None)}
    self.myclass = MyClass(**kwargs)

    ##later on
    def testDefaultEmailHeader():

        default_subject = "Hello World"
        self.myclass.publish()

        self.myclass.sendmail.assert_called()  #this is doing just fine
        self.myclass.sendmail.assert_called_with(default_subject)  #this is having issues

Pour une raison quelconque, je reçois le message d'erreur

AssertionError: Expected call: mock('Hello World')
                Actual Call : mock('defaultmt', 'defaultmf', 'Hello World', 'default_body', format= 'html')

Donc, fondamentalement, l'assertion s'attend à ce que sendmail soit appelé avec une seule variable, quand il finira par être appelé avec les 5. La chose est, je me fiche de ce que sont les 4 autres variables! Je veux juste m'assurer qu'il est appelé avec le bon sujet.

J'ai essayé le support de place simulé N'IMPORTE QUEL, et j'ai obtenu la même chose

self.myclass.sendmail.assert_called_with(ANY, ANY, 'Hello World', ANY, ANY)

AssertionError: Expected call: mock(<ANY>, <ANY>, 'Hello World', <ANY>, <ANY>)
Actual Call : mock('defaultmt', 'defaultmf', 'Hello World', 'default_body, 'format= 'html') 

Je ne sais vraiment pas comment procéder avec celui-ci. Quelqu'un a-t-il des conseils si nous ne nous soucions que de l'une des variables et que nous voulons ignorer le reste?

33
Zack

Si vous appelez sendmail avec un paramètre nommé subject, il est préférable de vérifier si l'argument nommé correspond à ce que vous attendez:

args, kwargs = self.myclass.sendmail.call_args
self.assertEqual(kwargs['subject'], "Hello World")

Cela suppose que les deux implémentations de sendmail ont un paramètre nommé appelé subject. Si ce n'est pas le cas, vous pouvez faire de même avec un paramètre positionnel:

args, kwargs = self.myclass.sendmail.call_args
self.assertTrue("Hello World" in args)

Vous pouvez être explicite sur la position de l'argument (c'est-à-dire le premier ou le troisième argument passé à sendmail mais cela dépend de l'implémentation de sendmail en cours de test).

34
Simeon Visser