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()
Here is the traceback
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. Why is this error thrown? They are <class type='MagicMock>
Q2. How do I pause the mocking so that the first line will pass if the error is fixed?
From the docs:
Normally the
__class__
attribute of an object will return its type. For a mock object with a spec,__class__
returns the spec class instead. This allows mock objects to passisinstance()
tests for the object they are replacing / masquerading as:
mock = Mock(spec=3)
isinstance(mock, int)
True
isinstance
is discouraged. – Skiinghasattr
doesn't seem to solve the gap either. Two objects may have same method names and uses the wrong object will make the test pass, I think? I guess the question's focus has shifted! Ahh. – TendencyHelloWorld
(after patching) isn't a class or a type, but amock.MagicMock
instance. As the error says, the second argument must be a class, type, or tuple of classes or types. Thespec
thing you refer to us for the first argument. That's what you're showing in your last example (from the docs). Why, exactly, do you wish to check whether yourHelloWorld
instance is an instance of an emulated type (which is, I think, impossible)? – Broomisinstance
in the particular module that it is used. – Ronnieronnyisinstance()
check because__instancecheck__
is officially unsupported magic method (by design). Butmock.NonCallableMagicMock
can be used as the second arg (see the answer below by klenwell). – Drily