我知道mock.path路径的基础知识,但是当对象被动态构造层封装时,计算出正确的路径变得越来越困难,例如。 django viewflow 如何模拟视图流处理程序
例如。
表格.py
def get_options():
# this is the one I want to mock
...
class Form(...):
field = Field(choices=get_options)
...
我只是在这里编造一些东西来展示一些复杂的情况 流.py
from forms import Form
class Flow(...):
start = (
flow.Start(..., form_class=Form).Next(...)
)
我已经尝试过
mock.patch('forms.get_options')
,但没有成功。我怀疑 get_options
参考资料已被更改。
我想知道是否有一些打印堆栈语句可以帮助向我显示我需要修补的路径,例如。
表格.py
def get_options():
# print the stack here and output something like
# "complicated_dynamic_class_creation.flow.instance.blah.blah.get_options"
# this is the one I want to mock
...
我还尝试获取函数正在执行的当前上下文的点符号
import inspect
def get_current_function_dot_notation():
# Get the current stack frame
frame = inspect.currentframe()
# Get the caller frame
caller_frame = frame.f_back
# Get the function name
function_name = caller_frame.f_code.co_name
# Get the module name
module_name = caller_frame.f_globals["__name__"]
# Try to get the class name (if the function is a method of a class)
class_name = None
if 'self' in caller_frame.f_locals:
class_name = caller_frame.f_locals['self'].__class__.__name__
elif 'cls' in caller_frame.f_locals:
class_name = caller_frame.f_locals['cls'].__name__
# Construct the dot notation
if class_name:
dot_notation = f"{module_name}.{class_name}.{function_name}"
else:
dot_notation = f"{module_name}.{function_name}"
return dot_notation
# Example usage
def get_options():
print(get_current_function_dot_notation())
...
这会返回“forms.get_options”,它在我的“流程”情况下不起作用。
模块级类定义在模块导入时执行,并且
field
的 Form
属性被初始化为 Field
对象(我认为你实际上是指这里的 ChoiceField
),其中 choices
是执行时参考get_options
。之后修补 forms.get_options
不会更改 choices
中存储为 field
的引用(在实际源代码中 choices
实际上是一个属性,在设置时存储可调用的返回值)。
更可行的方法是使用
patch.object
来修补 choices
的 Form.field
属性,这也是避免必须找出对象路径的方法(如果该类来自工厂):
with patch.object(Form.field, 'choices', Mock(return_value=['fixed choices', ...]):
...