当我调用 mock.patch 时,我希望它用我使用 new 关键字参数提供的类型替换我正在替换的类型。
它不会替换类型,但在patch.start()
调用时会返回正确的对象。
这FakesPatcher
是一种强制旧对象创建新对象的技巧。它适用于Python 3.x和PyPy。但是,它不适用于 Python 2.x。(见下面的编辑)。无论如何,
我希望它消失并使用。FakesPatcher
mock.patch
我在这里做错了什么,我该如何解决?
def substitute(obj, qualified_name, spec):
testdouble = mock.patch(qualified_name, spec=spec, spec_set=True, new=obj)
testdouble.attribute_name = qualified_name # Forces patch to use the extra patcher
class FakesPatcher(object):
"""Ugly hack."""
new = 1
def _new(*args, **kwargs):
return obj.__new__(obj)
def __enter__(self):
self._old_new = spec.__new__
spec.__new__ = self._new
return obj
def __exit__(self, exc_type, exc_val, exc_tb):
spec.__new__ = self._old_new
testdouble.additional_patchers.append(FakesPatcher())
return testdouble
def fake(obj):
"""
:rtype : mock._patch
:param obj:
"""
try:
configuration = obj.Configuration()
except AttributeError:
raise TypeError('A fake testdouble must have a Configuration class.')
try:
spec = configuration.spec
except AttributeError:
raise TestDoubleConfigurationError('The type to be faked was not specified.')
qualified_name = get_qualified_name(spec)
attrs = dict(obj.__dict__)
attrs.pop('Configuration')
methods = get_missing_methods(spec, obj)
for method in methods:
def make_default_implementation(attr):
def default_implementation(*args, **kwargs):
raise NotImplementedError('%s was not implemented when the object was faked.' % attr)
return default_implementation
attrs.update({method: make_default_implementation(method)})
properties = get_missing_properties(spec, obj)
for prop in properties:
def make_default_implementation(attr):
def default_implementation(*args, **kwargs):
raise NotImplementedError('%s was not implemented when the object was faked.' % attr)
return property(fget=lambda *args, **kwargs: default_implementation(*args, **kwargs),
fset=lambda *args, **kwargs: default_implementation(*args, **kwargs),
fdel=lambda *args, **kwargs: default_implementation(*args, **kwargs))
attrs.update({prop: make_default_implementation(prop)})
fake_qualified_name = get_qualified_name(obj)
obj = type(obj.__name__, obj.__bases__, attrs)
return substitute(obj, qualified_name, spec)
如果您想使用代码并对其进行测试,您可以在此处找到它。
编辑:
我通过用实例方法替换 lambda解决了 Python 2.x 错误。