web-dev-qa-db-fra.com

Comment obtenir le nombre d'appels en utilisant Mock @patch?

J'écris un test unitaire pour une bibliothèque sur laquelle nous travaillons. Cette bibliothèque utilise requests.post() pour effectuer POST requêtes HTTP vers un serveur externe.

À l'intérieur de mon UT, je ne veux évidemment pas contacter le vrai serveur mais me moquer de la réponse.

Pour ce faire, j'ai écrit une fonction qui va comme:

def mocked_post(url, headers, data, **kwargs):
    response = Mock()

    # Some logic, irrelevant here.

    return response

Et j'ai patché cette fonction autour de ma classe de test unitaire:

@patch('mylib.requests.post', mocked_post)
class MyTest(TestCase):

    def test_foo(self):
        # Some test logic

Cela fonctionne parfaitement.

Maintenant, je voudrais obtenir le nombre d'appels à ma fonction simulée. J'ai essayé mocked_post.call_count mais cela n'existe pas. J'ai essayé de trouver cette propriété sur de nombreux objets différents (dont mylib.requests.post) mais pas de chance jusqu'à présent.

Comment puis-je accéder au call_count pour cette fonction simulée?

24
ereOn

Je n'utiliserais pas mocked_post comme argument new ici. Je mettrais en place le side_effect attribut d'un nouveau Mock à la place:

@patch('mylib.requests.post')
class MyTest(TestCase):

    def test_foo(self, post_mock):
        post_mock.side_effect = mocked_post

        # Some test logic

        self.assertEqual(post_mock.call_count, 3)

Vous avez maintenant l'objet Mock que patch génère pour vous comme argument pour toutes vos méthodes de test, et vous pouvez ainsi tester combien de fois ce mock a été appelé.

Vous devriez pouvoir définir le side_effect attribut également dans le décorateur, à appliquer à tous les tests:

@patch('mylib.requests.post', side_effect=mocked_post)
class MyTest(TestCase):

    def test_foo(self, post_mock):
        # Some test logic

        self.assertEqual(post_mock.call_count, 3)

Vous aurez toujours du mal à accéder à l'objet response retourné, cependant; vous voudrez peut-être retourner mock.DEFAULT de mocked_post au lieu d'en créer un dans la fonction, pour pouvoir ensuite utiliser post_mock.return_value pour faire d'autres assertions sur l'objet retourné.

50
Martijn Pieters