【发布时间】:2012-06-21 21:03:42
【问题描述】:
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... 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.为什么会抛出这个错误?他们是<class type='MagicMock>
Q2.如果错误得到修复,如何暂停模拟以便第一行通过?
来自docs:
通常,对象的
__class__属性将返回其类型。对于具有规范的模拟对象,__class__返回规范类。这允许模拟对象通过isinstance()测试它们正在替换/伪装为的对象:
mock = Mock(spec=3)
isinstance(mock, int)
True
【问题讨论】:
-
现在你知道为什么不鼓励使用
isinstance了。 -
@MarkRansom 是的,它是邪恶的。但是确保我们传入的接口正确的最佳实践是什么?
hasattr似乎也没有解决这个问题。我认为两个对象可能具有相同的方法名称并使用错误的对象会使测试通过?我想问题的焦点已经转移了!啊。 -
谢谢马克。我觉得话题转移了。但是错误的问题还没有解决:(当我想到一个关于 isinstance 的更具体的问题时,我会发一个新帖子。谢谢!
-
您收到错误是因为
HelloWorld(修补后)不是类或类型,而是mock.MagicMock实例。正如错误所说,第二个参数必须是类、类型或类或类型的元组。您在 first 参数中引用我们的spec事物。这就是您在上一个示例中展示的内容(来自文档)。为什么,确切地说,您希望检查您的HelloWorld实例是否是模拟类型的实例(我认为这是不可能的)? -
"Python 的许多优点之一是它允许“Duck Typing”,只要它执行您想要的操作,您就不必关心对象的确切类型" - 直到它没有。
标签: python unit-testing mocking