85 votes

Utilisation du patch mock pour simuler une méthode d'instance

J'essaie de simuler quelque chose en testant une application Django à l'aide de l'outil imaginativement nommé Bibliothèque de tests simulés . Je n'arrive pas à le faire fonctionner, j'essaie de faire ça :

models.py

from somelib import FooClass

class Promotion(models.Model):
    foo = models.ForeignKey(FooClass)
    def bar(self):
       print "Do something I don't want!"

test.py

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    def test_enter_promotion(self):
        @patch.object(my_app.models.FooClass, 'bar')
        def fake_bar(self, mock_my_method):
            print "Do something I want!"
            return True

        self.client.get(reverse(view))

Qu'est-ce que je fais de mal ?

82voto

storm_m2138 Points 70

Pour ajouter à la réponse de Kit, spécifier un 3ème argument à patch.object() permet de spécifier l'objet/méthode simulée. Sinon, une valeur par défaut MagicMock est utilisé.

    def fake_bar(self):
        print "Do something I want!"
        return True

    @patch.object(my_app.models.FooClass, 'bar', fake_bar)
    def test_enter_promotion(self):
        self.client.get(reverse(view))
        # Do something I want!

Notez que, si vous spécifiez l'objet d'asservissement, alors la valeur par défaut MagicMock() est plus du tout passé dans l'objet corrigé -- par exemple, plus du tout :

def test_enter_promotion(self, mock_method):

mais à la place :

def test_enter_promotion(self):

https://docs.python.org/3/library/unittest.mock.html#patch-object

38voto

Kit Sunde Points 4026

Ah j'étais confus sur l'endroit où appliquer ce décorateur de patch. Corrigé :

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    @patch.object(my_app.models.FooClass, 'bar')
    def test_enter_promotion(self, mock_method):
        self.client.get(reverse(view))

3voto

Voy Points 1298

Si vous voulez faire assert_called etc. par rapport à la méthode simulée, utilisez la fonction patch.object et méthode de remplacement de l'enveloppe dans un MagicMock(side_effect=) c'est-à-dire :

with patch.object(class_to_mock, attribute_name, \
 MagicMock(side_effect=replacement_method)) as replacement_method_mock:

eg. :

from unittest.mock import patch, MagicMock

def fake_bar(self):
    print "Do something I want!"
    return True

def test_enter_promotion(self):
    with patch.object(my_app.models.FooClass, 'bar', MagicMock(side_effect=fake_bar)) as fake_bar_mock:
        self.client.get(reverse(view))
        # Do something I want!
        fake_bar_mock.assert_called()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X