Come si fa beffe di patch un pitone di classe e di ottenere un nuovo oggetto di simulazione per ogni istanza?

OK,

So che questo è menzionato nel manuale, e probabilmente ha a che fare con side_effect e/o return_value, ma un semplice e diretto esempio mi aiuterà immensamente.

Ho:

class ClassToPatch():
   def __init__(self, *args):
       _do_some_init_stuff()

   def some_func():
       _do_stuff()


class UUT():
    def __init__(self, *args)
       resource_1 = ClassToPatch()
       resource_2 = ClassToPatch()

Ora, voglio unit test il UUT classe, e prendere in giro la ClassToPatch. Conoscendo la UUT classe istanziare esattamente due ClassToPatch oggetti, voglio il Finto quadro per restituire un nuovo oggetto di simulazione per ciascuna istanza, così posso poi far valere invita, separatamente.

Come faccio a ottenere questo utilizzando il @patch decoratore in un caso di test? Vale a dire, come risolvere il seguente esempio di codice?

class TestCase1(unittest.TestCase):

    @patch('classToPatch.ClassToPatch',autospec=True)
    def test_1(self,mock1,mock2):
        _assert_stuff()
InformationsquelleAutor bavaza | 2012-05-25



One Reply
  1. 29

    Ecco un rapido n’piccolo esempio per farti andare:

    import mock
    import unittest
    
    class ClassToPatch():
       def __init__(self, *args):
           pass
    
       def some_func(self):
           return id(self)
    
    class UUT():
        def __init__(self, *args):
            resource_1 = ClassToPatch()
            resource_2 = ClassToPatch()
            self.test_property = (resource_1.some_func(), resource_2.some_func())
    
    class TestCase1(unittest.TestCase):
        @mock.patch('__main__.ClassToPatch', autospec = True)
        def test_1(self, mock1):
            ctpMocks = [mock.Mock(), mock.Mock()]
            ctpMocks[0].some_func.return_value = "funky"
            ctpMocks[1].some_func.return_value = "monkey"
            mock1.side_effect = ctpMocks
    
            u = UUT()
            self.assertEqual(u.test_property, ("funky", "monkey"))
    
    if __name__ == '__main__':
        unittest.main()

    Ho aggiunto test_property per UUT in modo che l’unità di test fa qualcosa di utile. Ora, senza il finto test_property dovrebbe essere una tupla contenente gli id dei due ClassToPatch istanze. Ma con il finto dovrebbe essere la tupla: ("funky", "monkey").

    Ho usato il side_effect proprietà dell’oggetto di simulazione, in modo che una diversa istanza di ClassToPatch è tornato a ogni chiamata in UUT initialiser.

    Spero che questo aiuta.

    Edit: Oh, a proposito, quando ho eseguito il test di unità ottengo:

    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.004s
    
    OK
    • (Nuova per Python:) Qualche modo per modificare il funzionamento in Python 2.7?
    • Ho appena eseguito questo codice in Python 2.7.9 (win32) e ha funzionato bene. L’errore che stai ricevendo?
    • ~ $ python –versione di Python 2.7.5 AttributeError: <modulo ‘principale‘ da ‘/home/russ/dev/eclipse/plugins/org.python.pydev_3.9.0.201411111611/pysrc/runfiles.py’> non hanno l’attributo ‘ClassToPatch’

Lascia un commento