我不确定为什么以下代码无效。我正在使用Mock framework。有人可以向我解释一下吗?
我得到的错误是:
$ python test_mock.py
Calls the mock object method. not a real one. ... ERROR
======================================================================
ERROR: Calls the mock object method. not a real one.
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_mock.py", line 37, in test_is_method_called
self.sut.do_something()
File "test_mock.py", line 21, in do_something
self.__obj.method()
File "build/bdist.linux-i686/egg/mock.py", line 365, in __getattr__
self._children[name] = self._get_child_mock(parent=self, name=name, wraps=wraps)
File "build/bdist.linux-i686/egg/mock.py", line 458, in _get_child_mock
return klass(**kw)
File "build/bdist.linux-i686/egg/mock.py", line 282, in __init__
self.reset_mock()
File "build/bdist.linux-i686/egg/mock.py", line 303, in reset_mock
self._return_value.reset_mock()
AttributeError: 'SentinelObject' object has no attribute 'reset_mock'
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
代码是:
import unittest
import mock
class Fubar ():
def __init__(self):
pass
def method (self):
print "I am a Stup!d Monkey!"
class Monkey ():
def __init__(self, obj):
self.__obj = obj
def do_something (self):
if not isinstance(self.__obj, Fubar):
raise RuntimeError
self.__obj.method()
class TestMoneky (unittest.TestCase):
def setUp(self):
self.mock_obj = mock.Mock(name="Mock object", spec=["method"])
self.sut = Monkey(self.mock_obj)
def tearDown(self):
pass
def test_is_method_called (self):
"""Calls the mock object method. not a real one."""
with mock.patch("__builtin__.isinstance") as mock_inst:
mock_inst.return_value = True
self.sut.do_something()
self.assertTrue(self.mock_obj.method.called)
def main ():
"""Simple runner."""
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestMoneky))
unittest.TextTestRunner(verbosity=2).run(suite)
if __name__ == '__main__':
main()
答案 0 :(得分:3)
问题(遗憾地)是微不足道的。我正在修补isinstance()
以始终返回True。所以,在模块内部的某个地方,有人问我的模拟对象是否是Sentinel并且(因为我重写了返回值),返回True。因此表现出错误的内部行为。
因此,解决方案不是修补isinstance()
,而是为模拟提供与其应匹配的类匹配的规范:
def setUp(self):
self.mock_obj = mock.Mock(name="Mock object", spec=Fubar)
self.sut = Monkey(self.mock_obj)
def test_is_method_called (self):
"""Calls the mock object method. not a real one."""
self.sut.do_something()
self.assertTrue(self.mock_obj.method.called)
任何人都可以看到这样做的方法没有将模拟耦合到Fubar
??? ...