class HelloWorld(object):
def say_it(self):
return 'Hello I am Hello World'
def i_call_hello_world(hw_obj):
print 'here... check type: %s' %type(HelloWorld)
if isinstance(hw_obj, HelloWorld):
print hw_obj.say_it()
from mock import patch, MagicMock
import unittest
class TestInstance(unittest.TestCase):
@patch('__main__.HelloWorld', spec=HelloWorld)
def test_mock(self,MK):
print type(MK)
MK.say_it.return_value = 'I am fake'
v = i_call_hello_world(MK)
print v
if __name__ == '__main__':
c = HelloWorld()
i_call_hello_world(c)
print isinstance(c, HelloWorld)
unittest.main()
Ecco la tracebackisinstance e beffardo
here... check type: <type 'type'>
Hello I am Hello World
True
<class 'mock.MagicMock'>
here... check type: <class 'mock.MagicMock'>
E
======================================================================
ERROR: test_mock (__main__.TestInstance)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1224, in patched
return func(*args, **keywargs)
File "t.py", line 18, in test_mock
v = i_call_hello_world(MK)
File "t.py", line 7, in i_call_hello_world
if isinstance(hw_obj, HelloWorld):
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
----------------------------------------------------------------------
Ran 1 test in 0.002s
Q1. Perché viene generato questo errore? Sono <class type='MagicMock>
Q2. Come faccio a mettere in pausa il mocking in modo che la prima riga passi se l'errore è stato risolto?
Dal doc
Normalmente il classe attributo di un oggetto tornerà suo tipo. Per un oggetto fittizio con una specifica classe restituisce invece la classe di specifica . Questo permette oggetti mock a superare test isinstance per l'oggetto che sostituiscono/mascherata da:
mock = Mock(spec=3)
isinstance(mock, int)
True
Grazie
Ora sai perché l'uso di 'isinstance' è scoraggiato. –
@MarkRansom Sì, è il male. Ma qual è la migliore pratica per garantire che l'interfaccia che passiamo sia CORRETTA? neanche "hasattr" sembra risolvere il problema. Due oggetti potrebbero avere gli stessi nomi di metodo e usare l'oggetto sbagliato faranno passare il test, credo? Immagino che l'attenzione della domanda si sia spostata! Ahh. – CppLearner
Questo è il punto: una delle molte cose carine di Python è che consente "Duck Typing" in cui non ti interessa il tipo esatto di un oggetto finché fa quello che vuoi. Potrebbe essere necessario fare attenzione alla denominazione dei metodi per assicurarsi di non definire lo stesso nome con due significati diversi, ma alla fine offre una grande flessibilità al codice. È una caratteristica, non un bug. –