python模拟库-在单元测试时修补类 [英] python mock library - patching classes while unit testing
问题描述
我无法理解模拟补丁的工作原理,以及它是否能够解决我的问题.
I cannot understand how mock patch works and if does it able to solve my problem.
我有3个文件:与外部接口(a.py),业务逻辑(b.py)和测试(test.py)的通信.我想在运行测试时修补业务逻辑使用的外部接口.
I have 3 files: communication with external interface (a.py), business logic (b.py) and tests (test.py). I want to patch external interface that is used by business logic while running tests.
a.py:
class SomeProductionClassINeedPatch(object):
name = 'Production Class (communication with some external service)'
def do_something(self):
print '<some feature with external service>'
b.py:
import mock
from src.tmp.mocks.a import SomeProductionClassINeedPatch
class WorkingClass(object):
def some_method_that_uses_external_class(self, *args):
external = self._external
external.do_something()
@property
def _external(self):
if not hasattr(self, '_ext_obj' or not self._ext_obj):
self._ext_obj = SomeProductionClassINeedPatch()
print isinstance(self._ext_obj, mock.MagicMock) # False
return self._ext_obj
b = WorkingClass()
b.some_method_that_uses_external_class()
test.py:
import mock
from src.tmp.mocks.b import WorkingClass # class I want to test
@mock.patch('src.tmp.mocks.a.SomeProductionClassINeedPatch')
def test_some_method_of_working_class(external_mock=None, *args):
o = WorkingClass()
o.some_method_that_uses_external_class() # external interface wasn't patched: <some feature with external service> - but I need mock here!
print '<test> - '+str(isinstance(o._external, mock.MagicMock)) # False
test_some_method_of_working_class()
我希望在 test.py 中调用o.some_method_that_uses_external_class()不会实际使用外部接口,而是使用模拟对象.但是似乎仍然使用实际的对象.
I expect that calling o.some_method_that_uses_external_class() in test.py will not actually use external interface, but mock object. But seems still actual object is used.
此外,当我在test.py或b.py中检查外部接口对象的实例时-我无法使它们通过 isinstance(object,MagicMock)检查,它始终返回false.即使我尝试在 b.py 中应用相同的补丁程序(作为类装饰器).我在做什么错了?
Also when I check instance of external interface object either in test.py or in b.py - I cannot make them to pass isinstance(object, MagicMock) check, it always return false. Even if I try to apply the same patch in b.py (as class decorator). What am I doing wrong?
如果重要的话,我使用python 2.7和Michael Foord的模拟库1.0.
I use python 2.7 and mock library 1.0 by Michael Foord if that matters.