找出Pythonmock.patch的正确路径

问题描述 投票:0回答:1

我知道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”,它在我的“流程”情况下不起作用。

python python-mock django-viewflow
1个回答
0
投票

模块级类定义在模块导入时执行,并且

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', ...]):
    ...
© www.soinside.com 2019 - 2024. All rights reserved.