gpt4 book ai didi

python 模拟库 - 在单元测试时修补类

转载 作者:太空宇宙 更新时间:2023-11-03 12:09:24 25 4
gpt4 key购买 nike

我不明白 mock patch 是如何工作的,它是否能解决我的问题。

我有 3 个文件:与外部接口(interface)通信 (a.py)、业务逻辑 (b.py) 和测试 (test.py)。我想修补运行测试时业务逻辑使用的外部接口(interface)。

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()

测试.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() 不会实际使用外部接口(interface),而是模拟对象。但似乎仍然使用实际对象。

此外,当我在 test.py 或 b.py 中检查外部接口(interface)对象的实例时 - 我无法让它们通过 isinstance(object, MagicMock) 检查,它总是返回 false。即使我尝试在 b.py 中应用相同的补丁(作为类装饰器)。我做错了什么?

如果重要的话,我会使用 python 2.7 和 Michael Foord 的模拟库 1.0。

最佳答案

Where to patch 中所述:

patch works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test.

在您的示例中,使用您要修补的对象的代码位于模块 b 中。当您调用 patch 时,该类已经导入到模块 b 中,因此修补 a 不会对 b 产生影响。您需要在 b 中为对象指定路径:

@mock.patch('src.tmp.mocks.b.SomeProductionClassINeedPatch')

这将为您提供预期的结果,来自 b 的第一次调用未打补丁,而来自 test 的第二次调用使用了模拟对象:

# python test.py
False
<some feature with external service>
True
<test> - True

关于python 模拟库 - 在单元测试时修补类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12317255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com